﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using SD.LLBLGen.Pro.QuerySpec;
using SD.LLBLGen.Pro.QuerySpec.Adapter;
using VNet.VisiSuite.BusinessLogic.BusinessException;
using VNet.VisiSuite.Common.Logger;
using VNet.VisiSuite.Common.Resource;
using VNet.VisiSuite.Dal.DatabaseSpecific;
using VNet.VisiSuite.Dal.EntityClasses;
using VNet.VisiSuite.Dal.FactoryClasses;
using VNet.VisiSuite.Dal.HelperClasses;
using VNet.VisiSuite.Service.Contact.Message.Base;
using VNet.VisiSuite.Service.Contact.Message.Item;

namespace VNet.VisiSuite.BusinessLogic
{
    public class AreaUtil
    {
        private QueryFactory _queryFactory = new QueryFactory();

        #region Area

        public SaveDataResponse<AreaItem> UpdateArea(SaveDataRequest<AreaItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var errorMessage = string.Empty;
                    if (!string.IsNullOrEmpty(errorMessage = CheckAreaNameUnique(adapter, request.Data)))
                        return new SaveDataResponse<AreaItem> { Success = false, Error = new ServiceError { Description = errorMessage, }, };

                    var areaQuery = _queryFactory.Area.Where(AreaFields.AreaId == request.Data.AreaId);
                    var areaEntity = adapter.FetchFirst(areaQuery);
                    if (areaEntity == null)
                        return new SaveDataResponse<AreaItem> { Success = false, Error = BusinessLogicError.AreaDoesNotExist };

                    areaEntity.LastUpdatedBy = request.Identity.UserLoginId;
                    areaEntity.LastUpdatedDate = DateTime.UtcNow;
                    areaEntity.AreaName = request.Data.AreaName;
                    areaEntity.Description = request.Data.Description;
                    areaEntity.Enabled = request.Data.Enabled;

                    if (!adapter.SaveEntity(areaEntity))
                        return new SaveDataResponse<AreaItem> { Success = false, Error = BusinessLogicError.UpdateAreaFailed };

                    // Get area entity after updated
                    var q = _queryFactory.Create()
                        .Select(() => new
                        {
                            Description = AreaFields.Description.Source("a").ToValue<string>(),
                            Enabled = AreaFields.Enabled.Source("a").ToValue<Boolean>(),
                            AreaName = AreaFields.AreaName.Source("a").ToValue<string>(),
                            LastUpdatedDate = AreaFields.LastUpdatedDate.Source("a").ToValue<DateTime>(),
                            AreaId = AreaFields.AreaId.Source("a").ToValue<int>(),
                            FirstName1 = (UserLoginFields.FirstName.Source("u").SetFieldAlias("FistName1")).ToValue<string>(),
                            LastName1 = (UserLoginFields.LastName.Source("u").SetFieldAlias("LastName1")).ToValue<string>(),
                        })
                        .From(_queryFactory.Area.As("a").InnerJoin(AreaEntity.Relations.UserLoginEntityUsingLastUpdatedBy, "a", "u"))
                        .Where(AreaFields.AreaId.Source("a") == request.Data.AreaId);

                    var val = adapter.FetchQuery(q).FirstOrDefault();
                    if (val == null)
                        return new SaveDataResponse<AreaItem> { Success = false, Error = BusinessLogicError.UpdateAreaFailed };

                    return new SaveDataResponse<AreaItem>
                    {
                        Success = true,
                        Data = new AreaItem
                        {
                            Description = val.Description,
                            AreaName = val.AreaName,
                            Enabled = val.Enabled,
                            AreaId = val.AreaId,
                            LastUpdatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            LastUpdatedDate = val.LastUpdatedDate,
                        }
                    };
                }
                catch (Exception ex)
                {
                    FileLog.Error("UpdateArea", ex);
                    return new SaveDataResponse<AreaItem> { Success = false, Error = BusinessLogicError.UpdateAreaFailed };
                }
            }


        }

        public SaveDataResponse<AreaItem> InsertArea(SaveDataRequest<AreaItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    //Check overlap
                    string errorMessage = null;
                    if (!string.IsNullOrEmpty(errorMessage = CheckAreaNameUnique(adapter, request.Data)))
                        return new SaveDataResponse<AreaItem> { Success = false, Error = new ServiceError { Description = errorMessage, }, };

                    var areaEntity = new AreaEntity();
                    var now = DateTime.UtcNow;
                    areaEntity.PlantId = request.Data.PlantId;
                    areaEntity.Description = request.Data.Description;
                    areaEntity.AreaName = request.Data.AreaName;
                    areaEntity.Enabled = request.Data.Enabled;
                    areaEntity.CreatedDate = now;
                    areaEntity.CreatedBy = request.Identity.UserLoginId;
                    areaEntity.LastUpdatedDate = now;
                    areaEntity.LastUpdatedBy = request.Identity.UserLoginId;

                    if (!adapter.SaveEntity(areaEntity, true))
                        return new SaveDataResponse<AreaItem> { Success = false, Error = BusinessLogicError.InsertAreaFailed };

                    // Get area entity after updated
                    var q = _queryFactory.Create()
                        .Select(() => new
                        {
                            PlantId = AreaFields.PlantId.Source("a").ToValue<int>(),
                            Description = AreaFields.Description.Source("a").ToValue<string>(),
                            AreaName = AreaFields.AreaName.Source("a").ToValue<string>(),
                            Enabled = AreaFields.Enabled.Source("a").ToValue<Boolean>(),
                            LastUpdatedDate = AreaFields.LastUpdatedDate.Source("a").ToValue<DateTime>(),
                            AreaId = AreaFields.AreaId.Source("a").ToValue<int>(),
                            FirstName1 = (UserLoginFields.FirstName.Source("u").SetFieldAlias("FistName1")).ToValue<string>(),
                            LastName1 = (UserLoginFields.LastName.Source("u").SetFieldAlias("LastName1")).ToValue<string>(),
                        })
                        .From(_queryFactory.Area.As("a").InnerJoin(AreaEntity.Relations.UserLoginEntityUsingLastUpdatedBy, "a", "u"))
                        .Where(AreaFields.AreaId.Source("a") == areaEntity.AreaId);

                    var val = adapter.FetchQuery(q).FirstOrDefault();
                    if (val == null)
                        return new SaveDataResponse<AreaItem> { Success = false, Error = BusinessLogicError.InsertAreaFailed };

                    return new SaveDataResponse<AreaItem>
                    {
                        Success = true,
                        Data = new AreaItem
                        {
                            PlantId = val.PlantId,
                            Description = val.Description,
                            AreaName = val.AreaName,
                            Enabled = val.Enabled,
                            AreaId = val.AreaId,
                            CreatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            CreatedDate = val.LastUpdatedDate,
                            LastUpdatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            LastUpdatedDate = val.LastUpdatedDate,
                        }
                    };
                }
                catch (Exception ex)
                {
                    FileLog.Error("InsertArea", ex);
                    return new SaveDataResponse<AreaItem> { Success = false, Error = BusinessLogicError.InsertAreaFailed };
                }
            }
        }

        public DeleteDataResponse DeleteArea(DeleteDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var query = _queryFactory.Create()
                                         .Select(CellShiftFields.CellShiftId)
                                         .From(_queryFactory.Cell.InnerJoin(_queryFactory.CellShift).On(CellFields.CellId == CellShiftFields.CellId))
                                         .Where(CellFields.AreaId == request.DataId);

                    var dataTable = adapter.FetchAsDataTable(query);
                    if (dataTable == null)
                        return new DeleteDataResponse { Success = false, Error = BusinessLogicError.DeleteAreaFailed };

                    if (dataTable.Rows.Count > 0)
                        return new DeleteDataResponse { Success = false, Error = new ServiceError { Description = string.Format(FormatString.CannotDeleteItem2, "area") }, };

                    var query2 = _queryFactory.Area.Where(AreaFields.AreaId == request.DataId);
                    var areaEntity = adapter.FetchFirst(query2);
                    if (areaEntity == null)
                        return new DeleteDataResponse { Error = BusinessLogicError.AreaDoesNotExist, Success = false };

                    if (!adapter.DeleteEntity(areaEntity))
                        return new DeleteDataResponse { Error = BusinessLogicError.DeleteAreaFailed, Success = false };

                    return new DeleteDataResponse { Success = true, DataId = request.DataId };
                }
                catch
                {
                    return new DeleteDataResponse { Success = false, Error = BusinessLogicError.DeleteAreaFailed };
                }
            }
        }

        private string CheckAreaNameUnique(DataAccessAdapter adapter, AreaItem data)
        {
            var query = _queryFactory.Area.Where(AreaFields.Enabled == true & AreaFields.AreaName == data.AreaName
                & AreaFields.PlantId == data.PlantId & AreaFields.AreaId != data.AreaId);
            var areas = (EntityCollection<AreaEntity>)adapter.FetchQuery(query);

            if (areas != null && areas.Count > 0)
                return ErrorMessages.ExistedAreaName;
            return null;
        }
        #endregion

        #region AreaShift
        public GetDataResponse<IList<AreaShiftItem>> GetAreaShifts(GetDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var areaShiftQuery = _queryFactory.AreaShift.WithPath(AreaShiftEntity.PrefetchPathUserLogin, AreaShiftEntity.PrefetchPathUserLogin1)
                                                                .Where(AreaShiftFields.Enabled == true).AndWhere(AreaShiftFields.AreaId == request.Id).OrderBy(AreaShiftFields.StartTime.Ascending());
                    EntityCollection<AreaShiftEntity> areaShiftEntities = (EntityCollection<AreaShiftEntity>)adapter.FetchQuery(areaShiftQuery);
                    if (areaShiftEntities == null)
                        return new GetDataResponse<IList<AreaShiftItem>> { Success = false, Error = BusinessLogicError.GetAreaShiftFailed };

                    var result = new List<AreaShiftItem>();
                    foreach (var areaShiftEntity in areaShiftEntities)
                    {
                        var areaShift = new AreaShiftItem
                        {
                            AreaShiftId = areaShiftEntity.AreaShiftId,
                            Description = areaShiftEntity.Description,
                            Enabled = areaShiftEntity.Enabled,
                            Hidden = areaShiftEntity.Hidden,
                            StartTime = areaShiftEntity.StartTime,
                            EndTime = areaShiftEntity.EndTime,
                            CreatedBy = string.Format("{0} {1}", areaShiftEntity.UserLogin.FirstName, areaShiftEntity.UserLogin.LastName),
                            LastUpdatedBy = string.Format("{0} {1}", areaShiftEntity.UserLogin1.FirstName, areaShiftEntity.UserLogin1.LastName),
                            CreatedDate = areaShiftEntity.CreatedDate,
                            LastUpdatedDate = areaShiftEntity.LastUpdatedDate,
                        };
                        result.Add(areaShift);
                    }

                    return new GetDataResponse<IList<AreaShiftItem>> { Success = true, Data = result };
                }
                catch (Exception ex)
                {
                    FileLog.Error("GetAreaShifts", ex);
                    return new GetDataResponse<IList<AreaShiftItem>> { Success = false, Error = BusinessLogicError.GetAreaShiftFailed };
                }
            }
        }

        public SaveDataResponse<AreaShiftItem> InsertAreaShift(SaveDataRequest<AreaShiftItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    //Check overlap
                    string errorMessage = null;
                    if (!string.IsNullOrEmpty(errorMessage = CheckAreaShiftOverlap(adapter, request.Data)))
                        return new SaveDataResponse<AreaShiftItem> { Success = false, Error = new ServiceError { Description = errorMessage, }, };
                    if (!string.IsNullOrEmpty(errorMessage = CheckAreaShiftDescriptionUnique(adapter, request.Data)))
                        return new SaveDataResponse<AreaShiftItem> { Success = false, Error = new ServiceError { Description = errorMessage, }, };

                    var areaShiftEntity = new AreaShiftEntity();
                    var now = DateTime.UtcNow;
                    areaShiftEntity.AreaId = request.Data.AreaId;
                    areaShiftEntity.Description = request.Data.Description;
                    areaShiftEntity.Enabled = request.Data.Enabled;
                    areaShiftEntity.Hidden = request.Data.Hidden;
                    areaShiftEntity.StartTime = request.Data.StartTime;
                    areaShiftEntity.EndTime = request.Data.EndTime;
                    areaShiftEntity.CreatedDate = now;
                    areaShiftEntity.CreatedBy = request.Identity.UserLoginId;
                    areaShiftEntity.LastUpdatedDate = now;
                    areaShiftEntity.LastUpdatedBy = request.Identity.UserLoginId;

                    if (!adapter.SaveEntity(areaShiftEntity, true))
                        return new SaveDataResponse<AreaShiftItem> { Success = false, Error = BusinessLogicError.InsertAreaShiftFailed };

                    // Get areaShift entity after updated
                    var q = _queryFactory.Create()
                        .Select(() => new
                        {
                            Description = AreaShiftFields.Description.Source("ars").ToValue<string>(),
                            StartTime = AreaShiftFields.StartTime.Source("ars").ToValue<TimeSpan>(),
                            EndTime = AreaShiftFields.EndTime.Source("ars").ToValue<TimeSpan>(),
                            Enabled = AreaShiftFields.Enabled.Source("ars").ToValue<Boolean>(),
                            Hidden = AreaShiftFields.Hidden.Source("ars").ToValue<Boolean>(),
                            LastUpdatedDate = AreaShiftFields.LastUpdatedDate.Source("ars").ToValue<DateTime>(),
                            AreaShiftId = AreaShiftFields.AreaShiftId.Source("ars").ToValue<int>(),
                            FirstName1 = (UserLoginFields.FirstName.Source("u").SetFieldAlias("FistName1")).ToValue<string>(),
                            LastName1 = (UserLoginFields.LastName.Source("u").SetFieldAlias("LastName1")).ToValue<string>(),
                        })
                        .From(_queryFactory.AreaShift.As("ars").InnerJoin(AreaShiftEntity.Relations.UserLoginEntityUsingLastUpdatedBy, "ars", "u"))
                        .Where(AreaShiftFields.AreaShiftId.Source("ars") == areaShiftEntity.AreaShiftId);

                    var val = adapter.FetchQuery(q).FirstOrDefault();
                    if (val == null)
                        return new SaveDataResponse<AreaShiftItem> { Success = false, Error = BusinessLogicError.InsertAreaShiftFailed };

                    return new SaveDataResponse<AreaShiftItem>
                    {
                        Success = true,
                        Data = new AreaShiftItem
                        {
                            Description = val.Description,
                            StartTime = val.StartTime,
                            EndTime = val.EndTime,
                            Enabled = val.Enabled,
                            Hidden = val.Hidden,
                            AreaShiftId = val.AreaShiftId,
                            CreatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            CreatedDate = val.LastUpdatedDate,
                            LastUpdatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            LastUpdatedDate = val.LastUpdatedDate,
                        }
                    };
                }
                catch (Exception ex)
                {
                    FileLog.Error("InsertAreaShift", ex);
                    return new SaveDataResponse<AreaShiftItem> { Success = false, Error = BusinessLogicError.InsertAreaShiftFailed };
                }
            }
        }

        public SaveDataResponse<AreaShiftItem> UpdateAreaShift(SaveDataRequest<AreaShiftItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    //Check existing cellShift related to the editing AreaShift
                    var cellShiftQuery = _queryFactory.CellShift.Where(CellShiftFields.AreaShiftId == request.Data.AreaShiftId).Include(CellShiftFields.CellShiftId).Select(CellShiftFields.CellShiftId);
                    var cellShift = adapter.FetchQuery(cellShiftQuery);
                    if (cellShift != null && cellShift.Count > 0)
                        return new SaveDataResponse<AreaShiftItem> { Success = false, Error = BusinessLogicError.CannotUpdateAreaShift };

                    //Check overlap
                    string errorMessage = null;
                    if (!string.IsNullOrEmpty(errorMessage = CheckAreaShiftOverlap(adapter, request.Data)))
                        return new SaveDataResponse<AreaShiftItem> { Success = false, Error = new ServiceError { Description = errorMessage, }, };

                    if (!string.IsNullOrEmpty(errorMessage = CheckAreaShiftDescriptionUnique(adapter, request.Data)))
                        return new SaveDataResponse<AreaShiftItem> { Success = false, Error = new ServiceError { Description = errorMessage, }, };

                    var areaShiftQuery = _queryFactory.AreaShift.Where(AreaShiftFields.AreaShiftId == request.Data.AreaShiftId);
                    var areaShiftEntity = adapter.FetchFirst(areaShiftQuery);
                    if (areaShiftEntity == null)
                        return new SaveDataResponse<AreaShiftItem> { Success = false, Error = BusinessLogicError.AreaShiftDoesNotExist };

                    areaShiftEntity.Description = request.Data.Description;
                    areaShiftEntity.Enabled = request.Data.Enabled;
                    areaShiftEntity.Hidden = request.Data.Hidden;
                    areaShiftEntity.StartTime = request.Data.StartTime;
                    areaShiftEntity.EndTime = request.Data.EndTime;
                    areaShiftEntity.LastUpdatedDate = DateTime.UtcNow;
                    areaShiftEntity.LastUpdatedBy = request.Identity.UserLoginId;

                    if (!adapter.SaveEntity(areaShiftEntity))
                        return new SaveDataResponse<AreaShiftItem> { Success = false, Error = BusinessLogicError.UpdateAreaShiftFailed };

                    // Get areaShift entity after updated
                    var q = _queryFactory.Create()
                        .Select(() => new
                        {
                            Description = AreaShiftFields.Description.Source("ars").ToValue<string>(),
                            StartTime = AreaShiftFields.StartTime.Source("ars").ToValue<TimeSpan>(),
                            EndTime = AreaShiftFields.EndTime.Source("ars").ToValue<TimeSpan>(),
                            Enabled = AreaShiftFields.Enabled.Source("ars").ToValue<Boolean>(),
                            Hidden = AreaShiftFields.Hidden.Source("ars").ToValue<Boolean>(),
                            LastUpdatedDate = AreaShiftFields.LastUpdatedDate.Source("ars").ToValue<DateTime>(),
                            AreaShiftId = AreaShiftFields.AreaShiftId.Source("ars").ToValue<int>(),
                            FirstName1 = (UserLoginFields.FirstName.Source("u").SetFieldAlias("FistName1")).ToValue<string>(),
                            LastName1 = (UserLoginFields.LastName.Source("u").SetFieldAlias("LastName1")).ToValue<string>(),
                        })
                        .From(_queryFactory.AreaShift.As("ars").InnerJoin(AreaShiftEntity.Relations.UserLoginEntityUsingLastUpdatedBy, "ars", "u"))
                        .Where(AreaShiftFields.AreaShiftId.Source("ars") == request.Data.AreaShiftId);

                    var val = adapter.FetchQuery(q).FirstOrDefault();
                    if (val == null)
                        return new SaveDataResponse<AreaShiftItem> { Success = false, Error = BusinessLogicError.UpdateAreaShiftFailed };

                    return new SaveDataResponse<AreaShiftItem>
                    {
                        Success = true,
                        Data = new AreaShiftItem
                        {
                            Description = val.Description,
                            StartTime = val.StartTime,
                            EndTime = val.EndTime,
                            Enabled = val.Enabled,
                            Hidden = val.Hidden,
                            AreaShiftId = val.AreaShiftId,
                            LastUpdatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            LastUpdatedDate = val.LastUpdatedDate,
                        }
                    };
                }
                catch (Exception ex)
                {
                    FileLog.Error("UpdateAreaShift", ex);
                    return new SaveDataResponse<AreaShiftItem> { Success = false, Error = BusinessLogicError.UpdateAreaShiftFailed };
                }
            }
        }

        public DeleteDataResponse DeleteAreaShift(DeleteDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var cellShiftQuery = _queryFactory.CellShift.Where(CellShiftFields.AreaShiftId == request.DataId).Include(CellShiftFields.CellShiftId).Select(CellShiftFields.CellShiftId);
                    var cellShift = adapter.FetchQuery(cellShiftQuery);
                    if (cellShift != null && cellShift.Count > 0)
                        return new DeleteDataResponse { Success = false, Error = BusinessLogicError.CannotDeleteAreaShift };

                    var query = _queryFactory.AreaShift.Where(AreaShiftFields.AreaShiftId == request.DataId);
                    var areaShiftEntity = adapter.FetchFirst(query);
                    if (areaShiftEntity == null)
                        return new DeleteDataResponse { Error = BusinessLogicError.AreaShiftDoesNotExist, Success = false };

                    if (!adapter.DeleteEntity(areaShiftEntity))
                        return new DeleteDataResponse { Error = BusinessLogicError.DeleteAreaShiftFailed, Success = false };

                    return new DeleteDataResponse { Success = true, DataId = request.DataId };
                }
                catch
                {
                    return new DeleteDataResponse { Success = false, Error = BusinessLogicError.DeleteAreaShiftFailed };
                }
            }
        }

        private string CheckAreaShiftOverlap(DataAccessAdapter adapter, AreaShiftItem data)
        {
            string errorMessage = null;
            if (data.StartTime == data.EndTime)
                return errorMessage;

            var areaShiftQuery = _queryFactory.AreaShift.Where(AreaShiftFields.AreaId == data.AreaId & AreaShiftFields.Enabled == true & AreaShiftFields.AreaShiftId != data.AreaShiftId)
                        .AndWhere((AreaShiftFields.StartTime < AreaShiftFields.EndTime) & ((AreaShiftFields.StartTime < data.EndTime & AreaShiftFields.EndTime > data.EndTime) | (AreaShiftFields.StartTime < data.StartTime & AreaShiftFields.EndTime > data.StartTime)));
            var overlapAreaShifts = (EntityCollection<AreaShiftEntity>)adapter.FetchQuery(areaShiftQuery);

            if (overlapAreaShifts != null && overlapAreaShifts.Count > 0)
            {
                errorMessage = ErrorMessages.OverlapAreaShift;
                foreach (var overlapAS in overlapAreaShifts)
                    errorMessage = string.Format("{0}{1}, ", errorMessage, overlapAS.Description);
                return errorMessage.Trim().Trim(',');
            }
            return errorMessage;
        }

        private string CheckAreaShiftDescriptionUnique(DataAccessAdapter adapter, AreaShiftItem data)
        {
            var areaShiftQuery = _queryFactory.AreaShift.Where(AreaShiftFields.AreaId == data.AreaId
                & AreaShiftFields.Enabled == true & AreaShiftFields.AreaShiftId != data.AreaShiftId
                & AreaShiftFields.Description == data.Description);
            var areaShifts = (EntityCollection<AreaShiftEntity>)adapter.FetchQuery(areaShiftQuery);

            if (areaShifts != null && areaShifts.Count > 0)
                return ErrorMessages.ExistedAreaShiftDescription;

            return null;
        }

        #endregion

        #region LaunchApplication
        public GetDataResponse<IList<LaunchApplicationItem>> GetLaunchApplications(GetDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var launchApplicationQuery = _queryFactory.LaunchApplication.WithPath(LaunchApplicationEntity.PrefetchPathUserLogin, LaunchApplicationEntity.PrefetchPathUserLogin1)
                                                                .Where(LaunchApplicationFields.Enabled == true).AndWhere(LaunchApplicationFields.AreaId == request.Id)
                                                                .OrderBy(LaunchApplicationFields.SortOrder.Ascending());
                    EntityCollection<LaunchApplicationEntity> launchApplicationEntities = (EntityCollection<LaunchApplicationEntity>)adapter.FetchQuery(launchApplicationQuery);
                    if (launchApplicationEntities == null)
                        return new GetDataResponse<IList<LaunchApplicationItem>> { Success = false, Error = BusinessLogicError.GetLaunchApplicationFailed };

                    var result = new List<LaunchApplicationItem>();
                    foreach (var launchApplicationEntity in launchApplicationEntities)
                    {
                        var launchApplication = new LaunchApplicationItem
                        {
                            LaunchApplicationId = launchApplicationEntity.LaunchApplicationId,
                            Description = launchApplicationEntity.Description,
                            Enabled = launchApplicationEntity.Enabled,
                            Application = launchApplicationEntity.Application,
                            Arguments = launchApplicationEntity.Arguments,
                            SortOrder = launchApplicationEntity.SortOrder,
                            CreatedBy = string.Format("{0} {1}", launchApplicationEntity.UserLogin.FirstName, launchApplicationEntity.UserLogin.LastName),
                            LastUpdatedBy = string.Format("{0} {1}", launchApplicationEntity.UserLogin1.FirstName, launchApplicationEntity.UserLogin1.LastName),
                            CreatedDate = launchApplicationEntity.CreatedDate,
                            LastUpdatedDate = launchApplicationEntity.LastUpdatedDate,
                        };
                        result.Add(launchApplication);
                    }

                    return new GetDataResponse<IList<LaunchApplicationItem>> { Success = true, Data = result };
                }
                catch (Exception ex)
                {
                    FileLog.Error("GetLaunchApplications", ex);
                    return new GetDataResponse<IList<LaunchApplicationItem>> { Success = false, Error = BusinessLogicError.GetLaunchApplicationFailed };
                }
            }
        }

        public SaveDataResponse<LaunchApplicationItem> InsertLaunchApplication(SaveDataRequest<LaunchApplicationItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var launchApplicationEntity = new LaunchApplicationEntity();
                    var now = DateTime.UtcNow;
                    launchApplicationEntity.Description = request.Data.Description;
                    launchApplicationEntity.AreaId = request.Data.AreaId;
                    launchApplicationEntity.Description = request.Data.Description;
                    launchApplicationEntity.Enabled = request.Data.Enabled;
                    launchApplicationEntity.Application = request.Data.Application;
                    launchApplicationEntity.Arguments = request.Data.Arguments;
                    launchApplicationEntity.SortOrder = request.Data.SortOrder;
                    launchApplicationEntity.CreatedDate = now;
                    launchApplicationEntity.CreatedBy = request.Identity.UserLoginId;
                    launchApplicationEntity.LastUpdatedDate = now;
                    launchApplicationEntity.LastUpdatedBy = request.Identity.UserLoginId;

                    if (!adapter.SaveEntity(launchApplicationEntity, true))
                        return new SaveDataResponse<LaunchApplicationItem> { Success = false, Error = BusinessLogicError.InsertLaunchApplicationFailed };

                    // Get launchApplication entity after updated
                    var q = _queryFactory.Create()
                        .Select(() => new
                        {
                            Description = LaunchApplicationFields.Description.Source("la").ToValue<string>(),
                            Enabled = LaunchApplicationFields.Enabled.Source("la").ToValue<Boolean>(),
                            Application = LaunchApplicationFields.Application.Source("la").ToValue<string>(),
                            Arguments = LaunchApplicationFields.Arguments.Source("la").ToValue<string>(),
                            SortOrder = LaunchApplicationFields.SortOrder.Source("la").ToValue<int>(),
                            LastUpdatedDate = LaunchApplicationFields.LastUpdatedDate.Source("la").ToValue<DateTime>(),
                            LaunchApplicationId = LaunchApplicationFields.LaunchApplicationId.Source("la").ToValue<int>(),
                            FirstName1 = (UserLoginFields.FirstName.Source("u").SetFieldAlias("FistName1")).ToValue<string>(),
                            LastName1 = (UserLoginFields.LastName.Source("u").SetFieldAlias("LastName1")).ToValue<string>(),
                        })
                        .From(_queryFactory.LaunchApplication.As("la").InnerJoin(LaunchApplicationEntity.Relations.UserLoginEntityUsingLastUpdatedBy, "la", "u"))
                        .Where(LaunchApplicationFields.LaunchApplicationId.Source("la") == launchApplicationEntity.LaunchApplicationId);

                    var val = adapter.FetchQuery(q).FirstOrDefault();
                    if (val == null)
                        return new SaveDataResponse<LaunchApplicationItem> { Success = false, Error = BusinessLogicError.InsertLaunchApplicationFailed };

                    return new SaveDataResponse<LaunchApplicationItem>
                    {
                        Success = true,
                        Data = new LaunchApplicationItem
                        {
                            Description = val.Description,
                            Application = val.Application,
                            Arguments = val.Arguments,
                            SortOrder = val.SortOrder,
                            Enabled = val.Enabled,
                            LaunchApplicationId = val.LaunchApplicationId,
                            CreatedDate = val.LastUpdatedDate,
                            CreatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            LastUpdatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            LastUpdatedDate = val.LastUpdatedDate,
                        }
                    };
                }
                catch (Exception ex)
                {
                    FileLog.Error("UpdateLaunchApplication", ex);
                    return new SaveDataResponse<LaunchApplicationItem> { Success = false, Error = BusinessLogicError.InsertLaunchApplicationFailed };
                }
            }
        }

        public SaveDataResponse<LaunchApplicationItem> UpdateLaunchApplication(SaveDataRequest<LaunchApplicationItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var launchApplicationQuery = _queryFactory.LaunchApplication.Where(LaunchApplicationFields.LaunchApplicationId == request.Data.LaunchApplicationId);
                    var launchApplicationEntity = adapter.FetchFirst(launchApplicationQuery);
                    if (launchApplicationEntity == null)
                        return new SaveDataResponse<LaunchApplicationItem> { Success = false, Error = BusinessLogicError.LaunchApplicationDoesNotExist };

                    launchApplicationEntity.Description = request.Data.Description;
                    launchApplicationEntity.Enabled = request.Data.Enabled;
                    launchApplicationEntity.Application = request.Data.Application;
                    launchApplicationEntity.Arguments = request.Data.Arguments;
                    launchApplicationEntity.SortOrder = request.Data.SortOrder;
                    launchApplicationEntity.LastUpdatedDate = DateTime.UtcNow;
                    launchApplicationEntity.LastUpdatedBy = request.Identity.UserLoginId;

                    if (!adapter.SaveEntity(launchApplicationEntity))
                        return new SaveDataResponse<LaunchApplicationItem> { Success = false, Error = BusinessLogicError.UpdateLaunchApplicationFailed };

                    // Get launchApplication entity after updated
                    var q = _queryFactory.Create()
                        .Select(() => new
                        {
                            Description = LaunchApplicationFields.Description.Source("la").ToValue<string>(),
                            Enabled = LaunchApplicationFields.Enabled.Source("la").ToValue<Boolean>(),
                            Application = LaunchApplicationFields.Application.Source("la").ToValue<string>(),
                            Arguments = LaunchApplicationFields.Arguments.Source("la").ToValue<string>(),
                            SortOrder = LaunchApplicationFields.SortOrder.Source("la").ToValue<int>(),
                            LastUpdatedDate = LaunchApplicationFields.LastUpdatedDate.Source("la").ToValue<DateTime>(),
                            LaunchApplicationId = LaunchApplicationFields.LaunchApplicationId.Source("la").ToValue<int>(),
                            FirstName1 = (UserLoginFields.FirstName.Source("u").SetFieldAlias("FistName1")).ToValue<string>(),
                            LastName1 = (UserLoginFields.LastName.Source("u").SetFieldAlias("LastName1")).ToValue<string>(),
                        })
                        .From(_queryFactory.LaunchApplication.As("la").InnerJoin(LaunchApplicationEntity.Relations.UserLoginEntityUsingLastUpdatedBy, "la", "u"))
                        .Where(LaunchApplicationFields.LaunchApplicationId.Source("la") == request.Data.LaunchApplicationId);

                    var val = adapter.FetchQuery(q).FirstOrDefault();
                    if (val == null)
                        return new SaveDataResponse<LaunchApplicationItem> { Success = false, Error = BusinessLogicError.UpdateLaunchApplicationFailed };

                    return new SaveDataResponse<LaunchApplicationItem>
                    {
                        Success = true,
                        Data = new LaunchApplicationItem
                        {
                            Description = val.Description,
                            Application = val.Application,
                            Arguments = val.Arguments,
                            SortOrder = val.SortOrder,
                            Enabled = val.Enabled,
                            LaunchApplicationId = val.LaunchApplicationId,
                            LastUpdatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            LastUpdatedDate = val.LastUpdatedDate,
                        }
                    };
                }
                catch (Exception ex)
                {
                    FileLog.Error("UpdateLaunchApplication", ex);
                    return new SaveDataResponse<LaunchApplicationItem> { Success = false, Error = BusinessLogicError.UpdateLaunchApplicationFailed };
                }
            }
        }

        public DeleteDataResponse DeleteLaunchApplication(DeleteDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var query = _queryFactory.LaunchApplication.Where(LaunchApplicationFields.LaunchApplicationId == request.DataId);
                    var launchApplicationEntity = adapter.FetchFirst(query);
                    if (launchApplicationEntity == null)
                        return new DeleteDataResponse { Error = BusinessLogicError.LaunchApplicationDoesNotExist, Success = false };

                    if (!adapter.DeleteEntity(launchApplicationEntity))
                        return new DeleteDataResponse { Error = BusinessLogicError.DeleteLaunchApplicationFailed, Success = false };

                    return new DeleteDataResponse { Success = true, DataId = request.DataId };
                }
                catch
                {
                    return new DeleteDataResponse { Success = false, Error = BusinessLogicError.DeleteLaunchApplicationFailed };
                }
            }
        }

        public SaveDataResponse<IList<LaunchApplicationItem>> MoveLaunchApplication(SaveDataRequest<LaunchApplicationItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                var result = new List<LaunchApplicationItem>();
                var query = _queryFactory.LaunchApplication.Where(LaunchApplicationFields.Enabled == true & LaunchApplicationFields.AreaId == request.Data.AreaId)
                                                               .OrderBy(LaunchApplicationFields.SortOrder.Ascending());
                try
                {

                    EntityCollection<LaunchApplicationEntity> entities = (EntityCollection<LaunchApplicationEntity>)adapter.FetchQuery(query);
                    if (entities == null)
                        return new SaveDataResponse<IList<LaunchApplicationItem>> { Success = false, Error = BusinessLogicError.MoveLaunchApplicationFailed };


                    var movingLa = entities.FirstOrDefault(t => t.LaunchApplicationId == request.Data.LaunchApplicationId);
                    if (movingLa == null)
                        return new SaveDataResponse<IList<LaunchApplicationItem>> { Success = false, Error = BusinessLogicError.MoveLaunchApplicationFailed };



                    //Reset all sort Order in case there is some record with Enabled = false
                    for (int i = 0; i < entities.Count; i++)
                    {
                        entities[i].SortOrder = i;
                    }

                    // request.Data.SortOrder is 1 if moving down, -1 if moving up
                    int currentIndex = entities.IndexOf(movingLa);
                    int affectedIndex = currentIndex + request.Data.SortOrder;
                    entities[currentIndex].SortOrder += request.Data.SortOrder;
                    entities[affectedIndex].SortOrder -= request.Data.SortOrder;

                    var ok = adapter.SaveEntityCollection(entities, true, false);
                    if (ok < 1)
                        return new SaveDataResponse<IList<LaunchApplicationItem>> { Success = false, Error = BusinessLogicError.MoveLaunchApplicationFailed };

                    for (int i = 0; i < entities.Count; i++)
                    {
                        result.Add(new LaunchApplicationItem
                        {
                            LaunchApplicationId = entities[i].LaunchApplicationId,
                            SortOrder = entities[i].SortOrder,
                        });
                    }

                    return new SaveDataResponse<IList<LaunchApplicationItem>> { Success = true, Data = result };
                }
                catch (Exception ex)
                {
                    FileLog.Error("GetLaunchApplications", ex);
                    return new SaveDataResponse<IList<LaunchApplicationItem>> { Success = false, Error = BusinessLogicError.MoveLaunchApplicationFailed };
                }
            }
        }

        #endregion

        #region ReasonCode
        public GetDataResponse<IList<ReasonCodeItem>> GetReasonCodes(GetDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var query = _queryFactory.ReasonCode
                        .WithPath(ReasonCodeEntity.PrefetchPathUserLogin, ReasonCodeEntity.PrefetchPathUserLogin1)
                        .Where(ReasonCodeFields.AreaId == request.Id)
                        .AndWhere(ReasonCodeFields.Scrap == false)
                        .OrderBy(ReasonCodeFields.Description.Ascending());
                    EntityCollection<ReasonCodeEntity> rcEntities = (EntityCollection<ReasonCodeEntity>)adapter.FetchQuery(query);
                    if (rcEntities == null)
                        return new GetDataResponse<IList<ReasonCodeItem>> { Success = false, Error = BusinessLogicError.GetReasonCodeFailed };

                    var result = new List<ReasonCodeItem>();
                    foreach (var entity in rcEntities)
                    {
                        var rc = new ReasonCodeItem
                        {
                            ReasonCodeId = entity.ReasonCodeId,
                            AreaId = entity.AreaId,
                            ParentId = entity.ParentId,
                            LinkId = entity.LinkId,
                            RollupDefinitionId = entity.RollupDefinitionId,
                            Level = entity.Level,
                            Description = entity.Description,
                            CreatedBy = string.Format("{0} {1}", entity.UserLogin.FirstName, entity.UserLogin.LastName),
                            LastUpdatedBy = string.Format("{0} {1}", entity.UserLogin1.FirstName, entity.UserLogin1.LastName),
                            CreatedDate = entity.CreatedDate,
                            LastUpdatedDate = entity.LastUpdatedDate,
                            IgnoreVisiBoxEvents = entity.IgnoreVisiBoxEvents,
                            Category = (ReasonCodeItem.ReasonCodeCategory)entity.Category,
                            ShopClockEvent = (ReasonCodeItem.ShopClockEventEnum)entity.ShopClockEvent,
                            HideChildren = entity.HideChildren,
                            FlashDelay = entity.FlashDelay,
                            Scrap = entity.Scrap,
                            DisplayInDowntimeChart = entity.DisplayInDowntimeChart,
                            IgnoreInOeeCalc = entity.IgnoreInOeeCalc,
                            IgnoreInWaitingCalc = entity.IgnoreInWaitingCalc,
                        };
                        result.Add(rc);
                    }
                    return new GetDataResponse<IList<ReasonCodeItem>> { Success = true, Data = result };
                }
                catch (Exception ex)
                {
                    FileLog.Error("GetReasonCodes", ex);
                    return new GetDataResponse<IList<ReasonCodeItem>> { Success = false, Error = BusinessLogicError.GetReasonCodeFailed };
                }
            }
        }

        public SaveDataResponse<ReasonCodeItem> InsertReasonCode(SaveDataRequest<ReasonCodeItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var rcEntity = new ReasonCodeEntity();
                    var now = DateTime.UtcNow;
                    rcEntity.AreaId = request.Data.AreaId;
                    rcEntity.Description = request.Data.Description;
                    rcEntity.ParentId = request.Data.ParentId;
                    rcEntity.LinkId = request.Data.LinkId;
                    rcEntity.RollupDefinitionId = request.Data.RollupDefinitionId;
                    rcEntity.Level = request.Data.Level;
                    rcEntity.IgnoreVisiBoxEvents = request.Data.IgnoreVisiBoxEvents;
                    rcEntity.Category = (short)request.Data.Category;
                    rcEntity.ShopClockEvent = (short)request.Data.ShopClockEvent;
                    rcEntity.HideChildren = request.Data.HideChildren;
                    rcEntity.FlashDelay = request.Data.FlashDelay;
                    rcEntity.Scrap = request.Data.Scrap;
                    rcEntity.DisplayInDowntimeChart = request.Data.DisplayInDowntimeChart;
                    rcEntity.IgnoreInOeeCalc = request.Data.IgnoreInOeeCalc;
                    rcEntity.IgnoreInWaitingCalc = request.Data.IgnoreInWaitingCalc;
                    rcEntity.CreatedDate = DateTime.UtcNow;
                    rcEntity.CreatedBy = request.Identity.UserLoginId;
                    rcEntity.LastUpdatedDate = DateTime.UtcNow;
                    rcEntity.LastUpdatedBy = request.Identity.UserLoginId;

                    if (!adapter.SaveEntity(rcEntity, true))
                        return new SaveDataResponse<ReasonCodeItem> { Success = false, Error = BusinessLogicError.InsertReasonCodeFailed };

                    // Get reasonCode entity after updated
                    var q = _queryFactory.Create()
                        .Select(() => new
                        {
                            Description = ReasonCodeFields.Description.Source("rc").ToValue<string>(),
                            ParentId = ReasonCodeFields.ParentId.Source("rc").ToValue<int?>(),
                            LinkId = ReasonCodeFields.LinkId.Source("rc").ToValue<int?>(),
                            RollupDefinitionId = ReasonCodeFields.RollupDefinitionId.Source("rc").ToValue<int?>(),
                            Level = ReasonCodeFields.Level.Source("rc").ToValue<int>(),
                            IgnoreVisiBoxEvents = ReasonCodeFields.IgnoreVisiBoxEvents.Source("rc").ToValue<bool>(),
                            Category = ReasonCodeFields.Category.Source("rc").ToValue<int>(),
                            HideChildren = ReasonCodeFields.HideChildren.Source("rc").ToValue<bool>(),
                            FlashDelay = ReasonCodeFields.FlashDelay.Source("rc").ToValue<short?>(),
                            Scrap = ReasonCodeFields.Scrap.Source("rc").ToValue<bool>(),
                            DisplayInDowntimeChart = ReasonCodeFields.DisplayInDowntimeChart.Source("rc").ToValue<bool>(),
                            IgnoreInOeeCalc = ReasonCodeFields.IgnoreInOeeCalc.Source("rc").ToValue<bool>(),
                            IgnoreInWaitingCalc = ReasonCodeFields.IgnoreInWaitingCalc.Source("rc").ToValue<bool>(),
                            CreatedDate = ReasonCodeFields.CreatedDate.Source("rc").ToValue<DateTime>(),
                            LastUpdatedDate = ReasonCodeFields.LastUpdatedDate.Source("rc").ToValue<DateTime>(),
                            ReasonCodeId = ReasonCodeFields.ReasonCodeId.Source("rc").ToValue<int>(),
                            AreaId = ReasonCodeFields.AreaId.Source("rc").ToValue<int>(),
                            FirstName = (UserLoginFields.FirstName.Source("u").SetFieldAlias("FistName")).ToValue<string>(),
                            LastName = (UserLoginFields.LastName.Source("u").SetFieldAlias("LastName")).ToValue<string>(),
                            FirstName1 = (UserLoginFields.FirstName.Source("u1").SetFieldAlias("FistName1")).ToValue<string>(),
                            LastName1 = (UserLoginFields.LastName.Source("u1").SetFieldAlias("LastName1")).ToValue<string>(),
                            ShopClockEvent = ReasonCodeFields.ShopClockEvent.Source("rc").ToValue<int>()
                        })
                        .From(_queryFactory.ReasonCode.As("rc").InnerJoin(ReasonCodeEntity.Relations.UserLoginEntityUsingCreatedBy, "rc", "u")
                                                               .InnerJoin(ReasonCodeEntity.Relations.UserLoginEntityUsingLastUpdatedBy, "rc", "u1"))
                        .Where(ReasonCodeFields.ReasonCodeId.Source("rc") == rcEntity.ReasonCodeId);

                    var val = adapter.FetchQuery(q).FirstOrDefault();
                    if (val == null)
                        return new SaveDataResponse<ReasonCodeItem> { Success = false, Error = BusinessLogicError.InsertReasonCodeFailed };

                    return new SaveDataResponse<ReasonCodeItem>
                    {
                        Success = true,
                        Data = new ReasonCodeItem
                        {
                            AreaId = val.AreaId,
                            Description = val.Description,
                            ParentId = val.ParentId,
                            LinkId = val.LinkId,
                            RollupDefinitionId = val.RollupDefinitionId,
                            Level = val.Level,
                            IgnoreVisiBoxEvents = val.IgnoreVisiBoxEvents,
                            Category = (ReasonCodeItem.ReasonCodeCategory)val.Category,
                            ShopClockEvent = (ReasonCodeItem.ShopClockEventEnum)val.ShopClockEvent,
                            HideChildren = val.HideChildren,
                            FlashDelay = val.FlashDelay,
                            Scrap = val.Scrap,
                            DisplayInDowntimeChart = val.DisplayInDowntimeChart,
                            IgnoreInOeeCalc = val.IgnoreInOeeCalc,
                            IgnoreInWaitingCalc = val.IgnoreInWaitingCalc,
                            ReasonCodeId = val.ReasonCodeId,
                            CreatedBy = string.Format(FormatString.NameFormat, val.FirstName, val.LastName),
                            CreatedDate = val.CreatedDate,
                            LastUpdatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            LastUpdatedDate = val.LastUpdatedDate,
                        }
                    };
                }
                catch (Exception ex)
                {
                    FileLog.Error("InsertReasonCode", ex);
                    return new SaveDataResponse<ReasonCodeItem> { Success = false, Error = BusinessLogicError.InsertReasonCodeFailed };
                }
            }
        }

        public SaveDataResponse<ReasonCodeItem> UpdateReasonCode(SaveDataRequest<ReasonCodeItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var reasonCodeQuery = _queryFactory.ReasonCode.Where(ReasonCodeFields.ReasonCodeId == request.Data.ReasonCodeId);
                    var reasonCodeEntity = adapter.FetchFirst(reasonCodeQuery);
                    if (reasonCodeEntity == null)
                        return new SaveDataResponse<ReasonCodeItem> { Success = false, Error = BusinessLogicError.ReasonCodeDoesNotExist };

                    reasonCodeEntity.Description = request.Data.Description;
                    reasonCodeEntity.ParentId = request.Data.ParentId;
                    reasonCodeEntity.LinkId = request.Data.LinkId;
                    reasonCodeEntity.RollupDefinitionId = request.Data.RollupDefinitionId;
                    reasonCodeEntity.Level = request.Data.Level;
                    reasonCodeEntity.IgnoreVisiBoxEvents = request.Data.IgnoreVisiBoxEvents;
                    reasonCodeEntity.Category = (short)request.Data.Category;
                    reasonCodeEntity.ShopClockEvent = (short)request.Data.ShopClockEvent;
                    reasonCodeEntity.HideChildren = request.Data.HideChildren;
                    reasonCodeEntity.FlashDelay = request.Data.FlashDelay;
                    reasonCodeEntity.Scrap = request.Data.Scrap;
                    reasonCodeEntity.DisplayInDowntimeChart = request.Data.DisplayInDowntimeChart;
                    reasonCodeEntity.IgnoreInWaitingCalc = request.Data.IgnoreInWaitingCalc;
                    reasonCodeEntity.IgnoreInOeeCalc = request.Data.IgnoreInOeeCalc;
                    reasonCodeEntity.LastUpdatedDate = DateTime.UtcNow;
                    reasonCodeEntity.LastUpdatedBy = request.Identity.UserLoginId;

                    if (!adapter.SaveEntity(reasonCodeEntity))
                        return new SaveDataResponse<ReasonCodeItem> { Success = false, Error = BusinessLogicError.UpdateReasonCodeFailed };

                    // Get reasonCode entity after updated
                    var q = _queryFactory.Create()
                        .Select(() => new
                        {
                            Description = ReasonCodeFields.Description.Source("rc").ToValue<string>(),
                            ParentId = ReasonCodeFields.ParentId.Source("rc").ToValue<int?>(),
                            LinkId = ReasonCodeFields.LinkId.Source("rc").ToValue<int?>(),
                            RollupDefinitionId = ReasonCodeFields.RollupDefinitionId.Source("rc").ToValue<int?>(),
                            Level = ReasonCodeFields.Level.Source("rc").ToValue<int>(),
                            IgnoreVisiBoxEvents = ReasonCodeFields.IgnoreVisiBoxEvents.Source("rc").ToValue<bool>(),
                            Category = ReasonCodeFields.Category.Source("rc").ToValue<int>(),
                            ShopClockEvent = ReasonCodeFields.ShopClockEvent.Source("rc").ToValue<int>(),
                            HideChildren = ReasonCodeFields.HideChildren.Source("rc").ToValue<bool>(),
                            FlashDelay = ReasonCodeFields.FlashDelay.Source("rc").ToValue<short?>(),
                            Scrap = ReasonCodeFields.Scrap.Source("rc").ToValue<bool>(),
                            DisplayInDowntimeChart = ReasonCodeFields.DisplayInDowntimeChart.Source("rc").ToValue<bool>(),
                            IgnoreInOeeCalc = ReasonCodeFields.IgnoreInOeeCalc.Source("rc").ToValue<bool>(),
                            IgnoreInWaitingCalc = ReasonCodeFields.IgnoreInWaitingCalc.Source("rc").ToValue<bool>(),
                            LastUpdatedDate = ReasonCodeFields.LastUpdatedDate.Source("rc").ToValue<DateTime>(),
                            ReasonCodeId = ReasonCodeFields.ReasonCodeId.Source("rc").ToValue<int>(),
                            FirstName1 = (UserLoginFields.FirstName.Source("u").SetFieldAlias("FistName1")).ToValue<string>(),
                            LastName1 = (UserLoginFields.LastName.Source("u").SetFieldAlias("LastName1")).ToValue<string>(),
                        })
                        .From(_queryFactory.ReasonCode.As("rc").InnerJoin(ReasonCodeEntity.Relations.UserLoginEntityUsingLastUpdatedBy, "rc", "u"))
                        .Where(ReasonCodeFields.ReasonCodeId.Source("rc") == request.Data.ReasonCodeId);

                    var val = adapter.FetchQuery(q).FirstOrDefault();
                    if (val == null)
                        return new SaveDataResponse<ReasonCodeItem> { Success = false, Error = BusinessLogicError.UpdateReasonCodeFailed };

                    return new SaveDataResponse<ReasonCodeItem>
                    {
                        Success = true,
                        Data = new ReasonCodeItem
                        {
                            Description = val.Description,
                            ParentId = val.ParentId,
                            LinkId = val.LinkId,
                            RollupDefinitionId = val.RollupDefinitionId,
                            Level = val.Level,
                            IgnoreVisiBoxEvents = val.IgnoreVisiBoxEvents,
                            Category = (ReasonCodeItem.ReasonCodeCategory)val.Category,
                            ShopClockEvent = (ReasonCodeItem.ShopClockEventEnum)val.ShopClockEvent,
                            HideChildren = val.HideChildren,
                            FlashDelay = val.FlashDelay,
                            Scrap = val.Scrap,
                            DisplayInDowntimeChart = val.DisplayInDowntimeChart,
                            IgnoreInWaitingCalc = val.IgnoreInWaitingCalc,
                            IgnoreInOeeCalc = val.IgnoreInOeeCalc,
                            ReasonCodeId = val.ReasonCodeId,
                            LastUpdatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            LastUpdatedDate = val.LastUpdatedDate,
                        }
                    };
                }
                catch (Exception ex)
                {
                    FileLog.Error("UpdateReasonCode", ex);
                    return new SaveDataResponse<ReasonCodeItem> { Success = false, Error = BusinessLogicError.UpdateReasonCodeFailed };
                }
            }
        }

        public DeleteDataResponse DeleteReasonCode(DeleteDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var query = _queryFactory.ReasonCode.Where(ReasonCodeFields.ReasonCodeId == request.DataId);
                    var reasonCodeEntity = adapter.FetchFirst(query);
                    if (reasonCodeEntity == null)
                        return new DeleteDataResponse { Error = BusinessLogicError.ReasonCodeDoesNotExist, Success = false };

                    if (!adapter.DeleteEntity(reasonCodeEntity))
                        return new DeleteDataResponse { Error = BusinessLogicError.DeleteReasonCodeFailed, Success = false };

                    return new DeleteDataResponse { Success = true, DataId = request.DataId };
                }
                catch
                {
                    return new DeleteDataResponse { Success = false, Error = BusinessLogicError.DeleteReasonCodeFailed };
                }
            }
        }

        public GetDataResponse<IList<RollupDefinitionItem>> GetRollupDefinitionsAsSource(GetDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var query = _queryFactory.RollupDefinition.Where(RollupDefinitionFields.AreaId == request.Id).OrderBy(RollupDefinitionFields.SortOrder.Ascending());
                    EntityCollection<RollupDefinitionEntity> rcEntities = (EntityCollection<RollupDefinitionEntity>)adapter.FetchQuery(query);
                    if (rcEntities == null)
                        return new GetDataResponse<IList<RollupDefinitionItem>> { Success = false, Error = BusinessLogicError.GetRollupDefinitionsAsSourceFailed };

                    var result = new List<RollupDefinitionItem>();
                    foreach (var entity in rcEntities)
                    {
                        var rd = new RollupDefinitionItem
                        {
                            RollupDefinitionId = entity.RollupDefinitionId,
                            Description = entity.Description,
                        };
                        result.Add(rd);
                    }
                    return new GetDataResponse<IList<RollupDefinitionItem>> { Success = true, Data = result };
                }
                catch (Exception ex)
                {
                    FileLog.Error("GetRollupDefinitionsAsSource", ex);
                    return new GetDataResponse<IList<RollupDefinitionItem>> { Success = false, Error = BusinessLogicError.GetRollupDefinitionsAsSourceFailed };
                }
            }
        }

        #endregion

        #region RollupDefinition
        public GetDataResponse<IList<RollupDefinitionItem>> GetRollupDefinitions(GetDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var query = _queryFactory.RollupDefinition.WithPath(RollupDefinitionEntity.PrefetchPathUserLogin, RollupDefinitionEntity.PrefetchPathUserLogin1)
                        .Where(RollupDefinitionFields.AreaId == request.Id).OrderBy(RollupDefinitionFields.SortOrder.Ascending());
                    EntityCollection<RollupDefinitionEntity> rcEntities = (EntityCollection<RollupDefinitionEntity>)adapter.FetchQuery(query);
                    if (rcEntities == null)
                        return new GetDataResponse<IList<RollupDefinitionItem>> { Success = false, Error = BusinessLogicError.GetRollupDefinitionsAsSourceFailed };

                    var result = new List<RollupDefinitionItem>();
                    foreach (var entity in rcEntities)
                    {
                        var rd = new RollupDefinitionItem
                        {
                            RollupDefinitionId = entity.RollupDefinitionId,
                            Description = entity.Description,
                            AreaId = entity.AreaId,
                            Color = entity.Color,
                            FontColor = entity.FontColor,
                            SortOrder = entity.SortOrder,
                            FlashingTimeout = entity.FlashingTimeout,
                            CreatedBy = string.Format("{0} {1}", entity.UserLogin.FirstName, entity.UserLogin.LastName),
                            LastUpdatedBy = string.Format("{0} {1}", entity.UserLogin1.FirstName, entity.UserLogin1.LastName),
                            CreatedDate = entity.CreatedDate,
                            LastUpdatedDate = entity.LastUpdatedDate,
                        };
                        result.Add(rd);
                    }
                    return new GetDataResponse<IList<RollupDefinitionItem>> { Success = true, Data = result };
                }
                catch (Exception ex)
                {
                    FileLog.Error("GetRollupDefinitions", ex);
                    return new GetDataResponse<IList<RollupDefinitionItem>> { Success = false, Error = BusinessLogicError.GetRollupDefinitionsFailed };
                }
            }
        }

        public SaveDataResponse<RollupDefinitionItem> InsertRollupDefinition(SaveDataRequest<RollupDefinitionItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    //Check unique for Description
                    string errorMessage = null;
                    if (!string.IsNullOrEmpty(errorMessage = CheckRollupDefinitionDescriptionUnique(adapter, request.Data)))
                        return new SaveDataResponse<RollupDefinitionItem> { Success = false, Error = new ServiceError { Description = errorMessage, }, };

                    var rollupDefEntity = new RollupDefinitionEntity();
                    var now = DateTime.UtcNow;
                    rollupDefEntity.AreaId = request.Data.AreaId;
                    rollupDefEntity.Description = request.Data.Description;
                    rollupDefEntity.Color = request.Data.Color;
                    rollupDefEntity.FontColor = request.Data.FontColor;
                    rollupDefEntity.FlashingTimeout = request.Data.FlashingTimeout;
                    rollupDefEntity.SortOrder = request.Data.SortOrder;
                    rollupDefEntity.CreatedDate = now;
                    rollupDefEntity.CreatedBy = request.Identity.UserLoginId;
                    rollupDefEntity.LastUpdatedDate = now;
                    rollupDefEntity.LastUpdatedBy = request.Identity.UserLoginId;

                    if (!adapter.SaveEntity(rollupDefEntity, true))
                        return new SaveDataResponse<RollupDefinitionItem> { Success = false, Error = BusinessLogicError.InsertRollupDefinitionFailed };

                    // Get rollupDef entity after updated
                    var q = _queryFactory.Create()
                        .Select(() => new
                        {
                            AreaId = RollupDefinitionFields.AreaId.Source("ars").ToValue<int>(),
                            Description = RollupDefinitionFields.Description.Source("ars").ToValue<string>(),
                            Color = RollupDefinitionFields.Color.Source("ars").ToValue<string>(),
                            FontColor = RollupDefinitionFields.FontColor.Source("ars").ToValue<string>(),
                            FlashingTimeout = RollupDefinitionFields.FlashingTimeout.Source("ars").ToValue<int>(),
                            SortOrder = RollupDefinitionFields.SortOrder.Source("ars").ToValue<int>(),
                            LastUpdatedDate = RollupDefinitionFields.LastUpdatedDate.Source("ars").ToValue<DateTime>(),
                            RollupDefinitionId = RollupDefinitionFields.RollupDefinitionId.Source("ars").ToValue<int>(),
                            FirstName1 = (UserLoginFields.FirstName.Source("u").SetFieldAlias("FistName1")).ToValue<string>(),
                            LastName1 = (UserLoginFields.LastName.Source("u").SetFieldAlias("LastName1")).ToValue<string>(),
                        })
                        .From(_queryFactory.RollupDefinition.As("ars").InnerJoin(RollupDefinitionEntity.Relations.UserLoginEntityUsingLastUpdatedBy, "ars", "u"))
                        .Where(RollupDefinitionFields.RollupDefinitionId.Source("ars") == rollupDefEntity.RollupDefinitionId);

                    var val = adapter.FetchQuery(q).FirstOrDefault();
                    if (val == null)
                        return new SaveDataResponse<RollupDefinitionItem> { Success = false, Error = BusinessLogicError.InsertRollupDefinitionFailed };

                    return new SaveDataResponse<RollupDefinitionItem>
                    {
                        Success = true,
                        Data = new RollupDefinitionItem
                        {
                            Description = val.Description,
                            Color = val.Color,
                            FontColor = val.FontColor,
                            FlashingTimeout = val.FlashingTimeout,
                            SortOrder = val.SortOrder,
                            AreaId = val.AreaId,
                            RollupDefinitionId = val.RollupDefinitionId,
                            CreatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            CreatedDate = val.LastUpdatedDate,
                            LastUpdatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            LastUpdatedDate = val.LastUpdatedDate,
                        }
                    };
                }
                catch (Exception ex)
                {
                    FileLog.Error("UpdateRollupDefinition", ex);
                    return new SaveDataResponse<RollupDefinitionItem> { Success = false, Error = BusinessLogicError.InsertRollupDefinitionFailed };
                }
            }
        }

        public SaveDataResponse<RollupDefinitionItem> UpdateRollupDefinition(SaveDataRequest<RollupDefinitionItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    //Check unique for Description
                    string errorMessage = null;
                    if (!string.IsNullOrEmpty(errorMessage = CheckRollupDefinitionDescriptionUnique(adapter, request.Data)))
                        return new SaveDataResponse<RollupDefinitionItem> { Success = false, Error = new ServiceError { Description = errorMessage, }, };

                    var rollupDefQuery = _queryFactory.RollupDefinition.Where(RollupDefinitionFields.RollupDefinitionId == request.Data.RollupDefinitionId);
                    var rollupDefEntity = adapter.FetchFirst(rollupDefQuery);
                    if (rollupDefEntity == null)
                        return new SaveDataResponse<RollupDefinitionItem> { Success = false, Error = BusinessLogicError.RollupDefinitionDoesNotExist };

                    rollupDefEntity.Description = request.Data.Description;
                    rollupDefEntity.Color = request.Data.Color;
                    rollupDefEntity.FontColor = request.Data.FontColor;
                    rollupDefEntity.FlashingTimeout = request.Data.FlashingTimeout;
                    rollupDefEntity.LastUpdatedDate = DateTime.UtcNow;
                    rollupDefEntity.LastUpdatedBy = request.Identity.UserLoginId;

                    if (!adapter.SaveEntity(rollupDefEntity))
                        return new SaveDataResponse<RollupDefinitionItem> { Success = false, Error = BusinessLogicError.UpdateRollupDefinitionFailed };

                    // Get rollupDef entity after updated
                    var q = _queryFactory.Create()
                        .Select(() => new
                        {
                            AreaId = RollupDefinitionFields.AreaId.Source("ars").ToValue<int>(),
                            Description = RollupDefinitionFields.Description.Source("ars").ToValue<string>(),
                            Color = RollupDefinitionFields.Color.Source("ars").ToValue<string>(),
                            FontColor = RollupDefinitionFields.FontColor.Source("ars").ToValue<string>(),
                            FlashingTimeout = RollupDefinitionFields.FlashingTimeout.Source("ars").ToValue<int>(),
                            LastUpdatedDate = RollupDefinitionFields.LastUpdatedDate.Source("ars").ToValue<DateTime>(),
                            RollupDefinitionId = RollupDefinitionFields.RollupDefinitionId.Source("ars").ToValue<int>(),
                            FirstName1 = (UserLoginFields.FirstName.Source("u").SetFieldAlias("FistName1")).ToValue<string>(),
                            LastName1 = (UserLoginFields.LastName.Source("u").SetFieldAlias("LastName1")).ToValue<string>(),
                        })
                        .From(_queryFactory.RollupDefinition.As("ars").InnerJoin(RollupDefinitionEntity.Relations.UserLoginEntityUsingLastUpdatedBy, "ars", "u"))
                        .Where(RollupDefinitionFields.RollupDefinitionId.Source("ars") == request.Data.RollupDefinitionId);

                    var val = adapter.FetchQuery(q).FirstOrDefault();
                    if (val == null)
                        return new SaveDataResponse<RollupDefinitionItem> { Success = false, Error = BusinessLogicError.UpdateRollupDefinitionFailed };

                    return new SaveDataResponse<RollupDefinitionItem>
                    {
                        Success = true,
                        Data = new RollupDefinitionItem
                        {
                            AreaId = val.AreaId,
                            Description = val.Description,
                            Color = val.Color,
                            FontColor = val.FontColor,
                            FlashingTimeout = val.FlashingTimeout,
                            RollupDefinitionId = val.RollupDefinitionId,
                            LastUpdatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            LastUpdatedDate = val.LastUpdatedDate,
                        }
                    };
                }
                catch (Exception ex)
                {
                    FileLog.Error("UpdateRollupDefinition", ex);
                    return new SaveDataResponse<RollupDefinitionItem> { Success = false, Error = BusinessLogicError.UpdateRollupDefinitionFailed };
                }
            }
        }

        public DeleteDataResponse DeleteRollupDefinition(DeleteDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var reasonCodeQuery = _queryFactory.ReasonCode.Where(ReasonCodeFields.RollupDefinitionId == request.DataId).Include(ReasonCodeFields.ReasonCodeId).Select(ReasonCodeFields.ReasonCodeId);
                    var reasonCode = adapter.FetchQuery(reasonCodeQuery);
                    if (reasonCode != null && reasonCode.Count > 0)
                        return new DeleteDataResponse { Success = false, Error = BusinessLogicError.CannotDeleteRollupDefinition };

                    var query = _queryFactory.RollupDefinition.Where(RollupDefinitionFields.RollupDefinitionId == request.DataId);
                    var rollupDefinitionEntity = adapter.FetchFirst(query);
                    if (rollupDefinitionEntity == null)
                        return new DeleteDataResponse { Error = BusinessLogicError.RollupDefinitionDoesNotExist, Success = false };

                    if (!adapter.DeleteEntity(rollupDefinitionEntity))
                        return new DeleteDataResponse { Error = BusinessLogicError.DeleteRollupDefinitionFailed, Success = false };

                    return new DeleteDataResponse { Success = true, DataId = request.DataId };
                }
                catch
                {
                    return new DeleteDataResponse { Success = false, Error = BusinessLogicError.DeleteRollupDefinitionFailed };
                }
            }
        }

        private string CheckRollupDefinitionDescriptionUnique(DataAccessAdapter adapter, RollupDefinitionItem data)
        {
            var rollupDefQuery = _queryFactory.RollupDefinition.Where(RollupDefinitionFields.AreaId == data.AreaId
                & RollupDefinitionFields.RollupDefinitionId != data.RollupDefinitionId
                & RollupDefinitionFields.Description == data.Description);
            var rollupDefinitions = (EntityCollection<RollupDefinitionEntity>)adapter.FetchQuery(rollupDefQuery);

            if (rollupDefinitions != null && rollupDefinitions.Count > 0)
                return ErrorMessages.ExistedRollupDefinitionDescription;

            return null;
        }

        public SaveDataResponse<IList<RollupDefinitionItem>> MoveRollupDefinition(SaveDataRequest<RollupDefinitionItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                var result = new List<RollupDefinitionItem>();
                var query = _queryFactory.RollupDefinition.Where(RollupDefinitionFields.AreaId == request.Data.AreaId)
                                                               .OrderBy(RollupDefinitionFields.SortOrder.Ascending());
                try
                {

                    EntityCollection<RollupDefinitionEntity> entities = (EntityCollection<RollupDefinitionEntity>)adapter.FetchQuery(query);
                    if (entities == null)
                        return new SaveDataResponse<IList<RollupDefinitionItem>> { Success = false, Error = BusinessLogicError.MoveRollupDefinitionFailed };


                    var movingLa = entities.FirstOrDefault(t => t.RollupDefinitionId == request.Data.RollupDefinitionId);
                    if (movingLa == null)
                        return new SaveDataResponse<IList<RollupDefinitionItem>> { Success = false, Error = BusinessLogicError.MoveRollupDefinitionFailed };

                    //Reset all sort Order in case there is some record is deleted
                    for (int i = 0; i < entities.Count; i++)
                    {
                        entities[i].SortOrder = i;
                    }

                    // request.Data.SortOrder is 1 if moving down, -1 if moving up
                    int currentIndex = entities.IndexOf(movingLa);
                    int affectedIndex = currentIndex + request.Data.SortOrder;
                    entities[currentIndex].SortOrder += request.Data.SortOrder;
                    entities[affectedIndex].SortOrder -= request.Data.SortOrder;

                    var ok = adapter.SaveEntityCollection(entities, true, false);
                    if (ok < 1)
                        return new SaveDataResponse<IList<RollupDefinitionItem>> { Success = false, Error = BusinessLogicError.MoveRollupDefinitionFailed };

                    for (int i = 0; i < entities.Count; i++)
                    {
                        result.Add(new RollupDefinitionItem
                        {
                            RollupDefinitionId = entities[i].RollupDefinitionId,
                            SortOrder = entities[i].SortOrder,
                        });
                    }

                    return new SaveDataResponse<IList<RollupDefinitionItem>> { Success = true, Data = result };
                }
                catch (Exception ex)
                {
                    FileLog.Error("GetRollupDefinitions", ex);
                    return new SaveDataResponse<IList<RollupDefinitionItem>> { Success = false, Error = BusinessLogicError.MoveRollupDefinitionFailed };
                }
            }
        }

        #endregion

        #region Alarm Setting
        public GetDataResponse<IList<AlarmSettingItem>> GetAlarmSettings(GetDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var query = _queryFactory.AlarmSetting.WithPath(AlarmSettingEntity.PrefetchPathUserLogin, AlarmSettingEntity.PrefetchPathUserLogin1)
                        .Where(AlarmSettingFields.AreaId == request.Id);
                    var rcEntities = (EntityCollection<AlarmSettingEntity>)adapter.FetchQuery(query);
                    if (rcEntities == null)
                        return new GetDataResponse<IList<AlarmSettingItem>> { Success = false, Error = BusinessLogicError.GetAlarmSettingsFailed };

                    var result = new List<AlarmSettingItem>();
                    foreach (var entity in rcEntities)
                    {
                        var rd = new AlarmSettingItem
                        {
                            AlarmSettingId = entity.AlarmSettingId,
                            AreaId = entity.AreaId,
                            Color = entity.Color,
                            FontColor = entity.FontColor,
                            MinPercentageBad = entity.MinPercentage100Bad,
                            MinPercentageGood = entity.MinPercentage100Good,
                            CreatedBy = string.Format("{0} {1}", entity.UserLogin.FirstName, entity.UserLogin.LastName),
                            LastUpdatedBy = string.Format("{0} {1}", entity.UserLogin1.FirstName, entity.UserLogin1.LastName),
                            CreatedDate = entity.CreatedDate,
                            LastUpdatedDate = entity.LastUpdatedDate,
                        };
                        result.Add(rd);
                    }
                    return new GetDataResponse<IList<AlarmSettingItem>> { Success = true, Data = result };
                }
                catch (Exception ex)
                {
                    FileLog.Error("GetAlarmSettings", ex);
                    return new GetDataResponse<IList<AlarmSettingItem>> { Success = false, Error = BusinessLogicError.GetAlarmSettingsFailed };
                }
            }
        }

        public SaveDataResponse<AlarmSettingItem> InsertAlarmSetting(SaveDataRequest<AlarmSettingItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var alarmSettingEntity = new AlarmSettingEntity();
                    var now = DateTime.UtcNow;
                    alarmSettingEntity.AreaId = request.Data.AreaId;
                    alarmSettingEntity.Color = request.Data.Color;
                    alarmSettingEntity.FontColor = request.Data.FontColor;
                    alarmSettingEntity.MinPercentage100Bad = request.Data.MinPercentageBad;
                    alarmSettingEntity.MinPercentage100Good = request.Data.MinPercentageGood;
                    alarmSettingEntity.CreatedDate = now;
                    alarmSettingEntity.CreatedBy = request.Identity.UserLoginId;
                    alarmSettingEntity.LastUpdatedDate = now;
                    alarmSettingEntity.LastUpdatedBy = request.Identity.UserLoginId;

                    if (!adapter.SaveEntity(alarmSettingEntity, true))
                        return new SaveDataResponse<AlarmSettingItem> { Success = false, Error = BusinessLogicError.InsertAlarmSettingFailed };

                    //// Get alarm setting entity after updated
                    //var q = _queryFactory.Create()
                    //    .Select(() => new
                    //    {
                    //        AreaId = AlarmSettingFields.AreaId.Source("ars").ToValue<int>(),
                    //        Color = AlarmSettingFields.Color.Source("ars").ToValue<string>(),
                    //        FontColor = AlarmSettingFields.FontColor.Source("ars").ToValue<string>(),
                    //        MinPercentage100Bad = AlarmSettingFields.MinPercentage100Bad.Source("ars").ToValue<short>(),
                    //        MinPercentage100Good = AlarmSettingFields.MinPercentage100Good.Source("ars").ToValue<short>(),
                    //        LastUpdatedDate = AlarmSettingFields.LastUpdatedDate.Source("ars").ToValue<DateTime>(),
                    //        AlarmSettingId = AlarmSettingFields.AlarmSettingId.Source("ars").ToValue<int>(),
                    //        FirstName1 = (UserLoginFields.FirstName.Source("u").SetFieldAlias("FistName1")).ToValue<string>(),
                    //        LastName1 = (UserLoginFields.LastName.Source("u").SetFieldAlias("LastName1")).ToValue<string>(),
                    //    })
                    //    .From(_queryFactory.AlarmSetting.As("ars").InnerJoin(AlarmSettingEntity.Relations.UserLoginEntityUsingLastUpdatedBy, "ars", "u"))
                    //    .Where(AlarmSettingFields.AlarmSettingId.Source("ars") == alarmSettingEntity.AlarmSettingId);

                    //var val = adapter.FetchQuery(q).FirstOrDefault();
                    //if (val == null)
                    //    return new SaveDataResponse<AlarmSettingItem> { Success = false, Error = BusinessLogicError.InsertAlarmSettingFailed };

                    //return new SaveDataResponse<AlarmSettingItem>
                    //{
                    //    Success = true,
                    //    Data = new AlarmSettingItem
                    //    {
                    //        Color = val.Color,
                    //        FontColor = val.FontColor,
                    //        MinPercentageGood = val.MinPercentage100Good,
                    //        MinPercentageBad = val.MinPercentage100Bad,
                    //        AreaId = val.AreaId,
                    //        AlarmSettingId = val.AlarmSettingId,
                    //        CreatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                    //        CreatedDate = val.LastUpdatedDate,
                    //        LastUpdatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                    //        LastUpdatedDate = val.LastUpdatedDate,
                    //    }
                    //};
                    return null;
                }
                catch (Exception ex)
                {
                    FileLog.Error("InsertAlarmSetting", ex);
                    return new SaveDataResponse<AlarmSettingItem> { Success = false, Error = BusinessLogicError.InsertAlarmSettingFailed };
                }
            }
        }

        public SaveDataResponse<AlarmSettingItem> UpdateAlarmSetting(SaveDataRequest<AlarmSettingItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var alarmSettingQuery = _queryFactory.AlarmSetting.Where(AlarmSettingFields.AlarmSettingId == request.Data.AlarmSettingId);
                    var alarmSettingEntity = adapter.FetchFirst(alarmSettingQuery);
                    if (alarmSettingEntity == null)
                        return new SaveDataResponse<AlarmSettingItem> { Success = false, Error = BusinessLogicError.AlarmSettingDoesNotExist };

                    alarmSettingEntity.Color = request.Data.Color;
                    alarmSettingEntity.FontColor = request.Data.FontColor;
                    alarmSettingEntity.MinPercentage100Bad = request.Data.MinPercentageBad;
                    alarmSettingEntity.MinPercentage100Good = request.Data.MinPercentageGood;
                    alarmSettingEntity.LastUpdatedDate = DateTime.UtcNow;
                    alarmSettingEntity.LastUpdatedBy = request.Identity.UserLoginId;

                    if (!adapter.SaveEntity(alarmSettingEntity))
                        return new SaveDataResponse<AlarmSettingItem> { Success = false, Error = BusinessLogicError.UpdateAlarmSettingFailed };

                    // Get rollupDef entity after updated
                    var q = _queryFactory.Create()
                        .Select(() => new
                        {
                            AreaId = AlarmSettingFields.AreaId.Source("ars").ToValue<int>(),
                            MinPercentage100Bad = AlarmSettingFields.MinPercentage100Bad.Source("ars").ToValue<short>(),
                            Color = AlarmSettingFields.Color.Source("ars").ToValue<string>(),
                            FontColor = AlarmSettingFields.FontColor.Source("ars").ToValue<string>(),
                            MinPercentage100Good = AlarmSettingFields.MinPercentage100Good.Source("ars").ToValue<short>(),
                            LastUpdatedDate = AlarmSettingFields.LastUpdatedDate.Source("ars").ToValue<DateTime>(),
                            AlarmSettingId = AlarmSettingFields.AlarmSettingId.Source("ars").ToValue<int>(),
                            FirstName1 = (UserLoginFields.FirstName.Source("u").SetFieldAlias("FistName1")).ToValue<string>(),
                            LastName1 = (UserLoginFields.LastName.Source("u").SetFieldAlias("LastName1")).ToValue<string>(),
                        })
                        .From(_queryFactory.AlarmSetting.As("ars").InnerJoin(AlarmSettingEntity.Relations.UserLoginEntityUsingLastUpdatedBy, "ars", "u"))
                        .Where(AlarmSettingFields.AlarmSettingId.Source("ars") == request.Data.AlarmSettingId);

                    var val = adapter.FetchQuery(q).FirstOrDefault();
                    if (val == null)
                        return new SaveDataResponse<AlarmSettingItem> { Success = false, Error = BusinessLogicError.UpdateAlarmSettingFailed };

                    return new SaveDataResponse<AlarmSettingItem>
                    {
                        Success = true,
                        Data = new AlarmSettingItem
                        {
                            AreaId = val.AreaId,
                            MinPercentageBad = val.MinPercentage100Bad,
                            Color = val.Color,
                            FontColor = val.FontColor,
                            MinPercentageGood = val.MinPercentage100Good,
                            AlarmSettingId = val.AlarmSettingId,
                            LastUpdatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            LastUpdatedDate = val.LastUpdatedDate,
                        }
                    };
                }
                catch (Exception ex)
                {
                    FileLog.Error("UpdateAlarmSetting", ex);
                    return new SaveDataResponse<AlarmSettingItem> { Success = false, Error = BusinessLogicError.UpdateAlarmSettingFailed };
                }
            }
        }

        public DeleteDataResponse DeleteAlarmSetting(DeleteDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var query = _queryFactory.AlarmSetting.Where(AlarmSettingFields.AlarmSettingId == request.DataId);
                    var alarmSettingEntity = adapter.FetchFirst(query);
                    if (alarmSettingEntity == null)
                        return new DeleteDataResponse { Error = BusinessLogicError.AlarmSettingDoesNotExist, Success = false };

                    if (!adapter.DeleteEntity(alarmSettingEntity))
                        return new DeleteDataResponse { Error = BusinessLogicError.DeleteAlarmSettingFailed, Success = false };

                    return new DeleteDataResponse { Success = true, DataId = request.DataId };
                }
                catch
                {
                    return new DeleteDataResponse { Success = false, Error = BusinessLogicError.DeleteAlarmSettingFailed };
                }
            }
        }
        
        #endregion

        #region ScrapReasonCode

        public GetDataResponse<IList<ReasonCodeItem>> GetScrapReasonCodes(GetDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var query = _queryFactory.ReasonCode.WithPath(ReasonCodeEntity.PrefetchPathUserLogin, ReasonCodeEntity.PrefetchPathUserLogin1)
                                                                .Where(ReasonCodeFields.AreaId == request.Id)
                                                                .AndWhere(ReasonCodeFields.Scrap == true)
                                                                .OrderBy(ReasonCodeFields.Description.Ascending());
                    EntityCollection<ReasonCodeEntity> rcEntities = (EntityCollection<ReasonCodeEntity>)adapter.FetchQuery(query);
                    if (rcEntities == null)
                        return new GetDataResponse<IList<ReasonCodeItem>> { Success = false, Error = BusinessLogicError.GetScrapReasonCodeFailed };

                    var result = new List<ReasonCodeItem>();
                    foreach (var entity in rcEntities)
                    {
                        var rc = new ReasonCodeItem
                        {
                            ReasonCodeId = entity.ReasonCodeId,
                            AreaId = entity.AreaId,
                            ParentId = entity.ParentId,
                            LinkId = entity.LinkId,
                            RollupDefinitionId = entity.RollupDefinitionId,
                            Level = entity.Level,
                            Description = entity.Description,
                            CreatedBy = string.Format("{0} {1}", entity.UserLogin.FirstName, entity.UserLogin.LastName),
                            LastUpdatedBy = string.Format("{0} {1}", entity.UserLogin1.FirstName, entity.UserLogin1.LastName),
                            CreatedDate = entity.CreatedDate,
                            LastUpdatedDate = entity.LastUpdatedDate,
                            IgnoreVisiBoxEvents = entity.IgnoreVisiBoxEvents,
                            Category = (ReasonCodeItem.ReasonCodeCategory)entity.Category,
                            HideChildren = entity.HideChildren,
                            FlashDelay = entity.FlashDelay,
                            Scrap = entity.Scrap,
                            DisplayInDowntimeChart = entity.DisplayInDowntimeChart,
                            IgnoreInOeeCalc = entity.IgnoreInOeeCalc,
                            IgnoreInWaitingCalc = entity.IgnoreInWaitingCalc
                        };
                        result.Add(rc);
                    }
                    return new GetDataResponse<IList<ReasonCodeItem>> { Success = true, Data = result };
                }
                catch (Exception ex)
                {
                    FileLog.Error("GetScrapReasonCodes", ex);
                    return new GetDataResponse<IList<ReasonCodeItem>> { Success = false, Error = BusinessLogicError.GetScrapReasonCodeFailed };
                }
            }
        }

        #endregion

        #region Scheduled Downtime

        public GetDataResponse<IList<ScheduledDowntimeItem>> GetScheduledDowntimes(GetDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var scheduledDowntimeQuery = _queryFactory.Schedule
                        .WithPath(ScheduleEntity.PrefetchPathUserLogin, ScheduleEntity.PrefetchPathUserLogin1)
                        .Where(ScheduleFields.AreaId == request.Id)
                        .OrderBy(ScheduleFields.StartTime.Ascending());
                    var scheduledDowntimeEntities = (EntityCollection<ScheduleEntity>)adapter.FetchQuery(scheduledDowntimeQuery);

                    if (scheduledDowntimeEntities == null)
                    {
                        return new GetDataResponse<IList<ScheduledDowntimeItem>>
                        {
                            Success = false,
                            Error = BusinessLogicError.GetScheduledDowntimeFailed
                        };
                    }

                    //List<ScheduledDowntimeItem> result = scheduledDowntimeEntities
                    //    .Select(scheduledDowntimeEntity => new ScheduledDowntimeItem
                    //    {
                    //        ScheduleId = scheduledDowntimeEntity.ScheduleId,
                    //        AreaId = scheduledDowntimeEntity.AreaId,
                    //        Subject = scheduledDowntimeEntity.Subject,
                    //        ReasonCode = scheduledDowntimeEntity.ReasonCode.Description,
                    //        StartTime = scheduledDowntimeEntity.StartTime,
                    //        EndTime = scheduledDowntimeEntity.EndTime,
                    //        ScheduleRepeatId = scheduledDowntimeEntity.ScheduleRepeatId,
                    //        CreatedBy = string.Format("{0} {1}",
                    //            scheduledDowntimeEntity.UserLogin.FirstName,
                    //            scheduledDowntimeEntity.UserLogin.LastName),
                    //        LastUpdatedBy = string.Format("{0} {1}",
                    //            scheduledDowntimeEntity.UserLogin1.FirstName,
                    //            scheduledDowntimeEntity.UserLogin1.LastName),
                    //        CreatedDate = scheduledDowntimeEntity.CreatedDate,
                    //        LastUpdatedDate = scheduledDowntimeEntity.LastUpdatedDate,
                    //    })
                    //    .ToList();
                    var result = new List<ScheduledDowntimeItem>();
                    foreach (var entity in scheduledDowntimeEntities)
                    {
                        result.Add(new ScheduledDowntimeItem
                        {
                            ScheduleId = entity.ScheduleId,
                            AreaId = entity.AreaId,
                            Subject = entity.Subject,
                            ReasonCodeId = entity.ReasonCodeId,
                            StartTime = entity.StartTime,
                            EndTime = entity.EndTime,
                            ScheduleRepeatId = entity.ScheduleRepeatId,
                            CreatedBy = string.Format("{0} {1}",
                                        entity.UserLogin.FirstName,
                                        entity.UserLogin.LastName),
                            LastUpdatedBy = string.Format("{0} {1}",
                                        entity.UserLogin1.FirstName,
                                        entity.UserLogin1.LastName),
                            CreatedDate = entity.CreatedDate,
                            LastUpdatedDate = entity.LastUpdatedDate,
                        });
                    }

                    return new GetDataResponse<IList<ScheduledDowntimeItem>> {Success = true, Data = result};
                }
                catch (Exception ex)
                {
                    FileLog.Error("GetScheduledDowntimes", ex);
                    return new GetDataResponse<IList<ScheduledDowntimeItem>>
                    {
                        Success = false,
                        Error = BusinessLogicError.GetScheduledDowntimeFailed
                    };
                }
            }
        }


        public SaveDataResponse<ScheduledDowntimeItem> InsertScheduleTime(SaveDataRequest<ScheduledDowntimeItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var scheduleEntity = new ScheduleEntity();
                    var now = DateTime.UtcNow;
                    scheduleEntity.AreaId = request.Data.AreaId;
                    scheduleEntity.Subject = request.Data.Subject;
                    scheduleEntity.ReasonCodeId = request.Data.ReasonCodeId;
                    scheduleEntity.StartTime = request.Data.StartTime;
                    scheduleEntity.EndTime = request.Data.EndTime;
                    scheduleEntity.ScheduleRepeatId = request.Data.ScheduleRepeatId;
                    scheduleEntity.CreatedDate = now;
                    scheduleEntity.CreatedBy = request.Identity.UserLoginId;
                    scheduleEntity.LastUpdatedDate = now;
                    scheduleEntity.LastUpdatedBy = request.Identity.UserLoginId;

                    if (!adapter.SaveEntity(scheduleEntity, true))
                        return new SaveDataResponse<ScheduledDowntimeItem> { Success = false, Error = BusinessLogicError.InsertScheduleFailed };

                    // Get ScheduledDowntime entity after insert
                    var q = _queryFactory.Create()
                        .Select(() => new
                        {
                            AreaId = ScheduleFields.AreaId.Source("sd").ToValue<int>(),
                            ScheduleID = ScheduleFields.ScheduleId.Source("sd").ToValue<int>(),
                            Subject = ScheduleFields.Subject.Source("sd").ToValue<string>(),
                            ReasonCodeId = ScheduleFields.ReasonCodeId.Source("sd").ToValue<int>(),
                            StartTime = ScheduleFields.StartTime.Source("sd").ToValue<DateTime>(),
                            EndTime = ScheduleFields.EndTime.Source("sd").ToValue<DateTime>(),
                            ScheduleRepeatId = ScheduleFields.ScheduleRepeatId.Source("sd").ToValue<short>(),
                            LastUpdatedDate = ScheduleFields.LastUpdatedDate.Source("sd").ToValue<DateTime>(),
                            FirstName1 = (UserLoginFields.FirstName.Source("u").SetFieldAlias("FistName1")).ToValue<string>(),
                            LastName1 = (UserLoginFields.LastName.Source("u").SetFieldAlias("LastName1")).ToValue<string>(),
                        })
                        .From(_queryFactory.Schedule.As("sd").InnerJoin(ScheduleEntity.Relations.UserLoginEntityUsingLastUpdatedBy, "sd", "u"))
                        .Where(ScheduleFields.ScheduleId.Source("sd") == scheduleEntity.ScheduleId);

                    var val = adapter.FetchQuery(q).FirstOrDefault();
                    if (val == null)
                        return new SaveDataResponse<ScheduledDowntimeItem> { Success = false, Error = BusinessLogicError.InsertScheduleFailed };

                    return new SaveDataResponse<ScheduledDowntimeItem>
                    {
                        Success = true,
                        Data = new ScheduledDowntimeItem
                        {
                            AreaId = val.AreaId,
                            ScheduleId = val.ScheduleID,
                            Subject = val.Subject,
                            ReasonCodeId = val.ReasonCodeId,
                            StartTime = val.StartTime,
                            EndTime = val.EndTime,
                            ScheduleRepeatId = val.ScheduleRepeatId,
                            CreatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            CreatedDate = val.LastUpdatedDate,
                            LastUpdatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            LastUpdatedDate = val.LastUpdatedDate,
                        }
                    };

                    //return null;

                }
                catch (Exception ex)
                {
                    FileLog.Error("InsertScheduledDowntime", ex);
                    return new SaveDataResponse<ScheduledDowntimeItem> { Success = false, Error = BusinessLogicError.InsertScheduleFailed };
                }
            }
        }


        public SaveDataResponse<ScheduledDowntimeItem> UpdateScheduledDowntime(SaveDataRequest<ScheduledDowntimeItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var scheduleDowntimeQuery = _queryFactory.Schedule.Where(ScheduleFields.ScheduleId == request.Data.ScheduleId);
                    var scheduleDowntimeEntity = adapter.FetchFirst(scheduleDowntimeQuery);
                    if (scheduleDowntimeEntity == null)
                        return new SaveDataResponse<ScheduledDowntimeItem> { Success = false, Error = BusinessLogicError.ScheduledDowntimeDoesNotExist };

                    scheduleDowntimeEntity.AreaId = request.Data.AreaId;
                    scheduleDowntimeEntity.Subject = request.Data.Subject;
                    scheduleDowntimeEntity.ReasonCodeId = request.Data.ReasonCodeId;
                    scheduleDowntimeEntity.StartTime = request.Data.StartTime;
                    scheduleDowntimeEntity.EndTime = request.Data.EndTime;
                    scheduleDowntimeEntity.ScheduleRepeatId = request.Data.ScheduleRepeatId;

                    scheduleDowntimeEntity.LastUpdatedDate = DateTime.UtcNow;
                    scheduleDowntimeEntity.LastUpdatedBy = request.Identity.UserLoginId;

                    if (!adapter.SaveEntity(scheduleDowntimeEntity))
                        return new SaveDataResponse<ScheduledDowntimeItem> { Success = false, Error = BusinessLogicError.UpdateScheduledDowntimeFailed };


                    // Get rollupDef entity after updated
                    var q = _queryFactory.Create()
                        .Select(() => new
                        {
                            AreaId = ScheduleFields.AreaId.Source("sd").ToValue<int>(),
                            ScheduleID = ScheduleFields.ScheduleId.Source("sd").ToValue<int>(),
                            Subject = ScheduleFields.Subject.Source("sd").ToValue<string>(),
                            ReasonCodeId = ScheduleFields.ReasonCodeId.Source("sd").ToValue<int>(),
                            StartTime = ScheduleFields.StartTime.Source("sd").ToValue<DateTime>(),
                            EndTime = ScheduleFields.EndTime.Source("sd").ToValue<DateTime>(),
                            ScheduleRepeatId = ScheduleFields.ScheduleRepeatId.Source("sd").ToValue<short>(),
                            LastUpdatedDate = ScheduleFields.LastUpdatedDate.Source("sd").ToValue<DateTime>(),
                            FirstName1 = (UserLoginFields.FirstName.Source("u").SetFieldAlias("FistName1")).ToValue<string>(),
                            LastName1 = (UserLoginFields.LastName.Source("u").SetFieldAlias("LastName1")).ToValue<string>(),
                        })
                        .From(_queryFactory.Schedule.As("sd").InnerJoin(ScheduleEntity.Relations.UserLoginEntityUsingLastUpdatedBy, "sd", "u"))
                        .Where(ScheduleFields.ScheduleId.Source("sd") == request.Data.ScheduleId);

                    var val = adapter.FetchQuery(q).FirstOrDefault();
                    if (val == null)
                        return new SaveDataResponse<ScheduledDowntimeItem> { Success = false, Error = BusinessLogicError.UpdateScheduledDowntimeFailed };

                    return new SaveDataResponse<ScheduledDowntimeItem>
                    {
                        Success = true,
                        Data = new ScheduledDowntimeItem
                        {
                            AreaId = val.AreaId,
                            ScheduleId = val.ScheduleID,
                            Subject = val.Subject,
                            ReasonCodeId = val.ReasonCodeId,
                            StartTime = val.StartTime,
                            EndTime = val.EndTime,
                            ScheduleRepeatId = val.ScheduleRepeatId,
                            //CreatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            //CreatedDate = val.LastUpdatedDate,
                            LastUpdatedBy = string.Format(FormatString.NameFormat, val.FirstName1, val.LastName1),
                            LastUpdatedDate = val.LastUpdatedDate,
                        }
                    };
                }
                catch (Exception ex)
                {
                    FileLog.Error("UpdateScheduledDowntime", ex);
                    return new SaveDataResponse<ScheduledDowntimeItem> { Success = false, Error = BusinessLogicError.UpdateScheduledDowntimeFailed };
                }
            }
        }


        public DeleteDataResponse DeleteSchedulerdDowntime(DeleteDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var query = _queryFactory.Schedule.Where(ScheduleFields.ScheduleId == request.DataId);
                    var scheduledDowntimeEntity = adapter.FetchFirst(query);
                    if (scheduledDowntimeEntity == null)
                        return new DeleteDataResponse { Error = BusinessLogicError.ScheduledDowntimeDoesNotExist, Success = false };

                    if (!adapter.DeleteEntity(scheduledDowntimeEntity))
                        return new DeleteDataResponse { Error = BusinessLogicError.DeleteScheduledDowntimeFailed, Success = false };

                    return new DeleteDataResponse { Success = true, DataId = request.DataId };
                }
                catch
                {
                    return new DeleteDataResponse { Success = false, Error = BusinessLogicError.DeleteScheduledDowntimeFailed };
                }
            }
        }



        #endregion

        #region Schedule Repeat

        public GetDataResponse<IList<ScheduledRepeatItem>> GetScheduledRepeat(GetDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var scheduledRepeatQuery = _queryFactory.ScheduleRepeat
                        .Where(ScheduleRepeatFields.ScheduleRepeatId == request.Id)
                        .OrderBy(ScheduleRepeatFields.ScheduleRepeatId.Ascending());
                    var scheduledRepeatEntities = (EntityCollection<ScheduleRepeatEntity>)adapter.FetchQuery(scheduledRepeatQuery);

                    if (scheduledRepeatEntities == null)
                    {
                        return new GetDataResponse<IList<ScheduledRepeatItem>>
                        {
                            Success = false,
                            Error = BusinessLogicError.GetScheduleRepeatFailed
                        };
                    }

                    var result = new List<ScheduledRepeatItem>();
                    foreach (var entity in scheduledRepeatEntities)
                    {
                        result.Add(new ScheduledRepeatItem
                        {
                            ScheduleRepeatID = entity.ScheduleRepeatId,
                            IsOneTime = entity.IsOneTime,
                            IsEveryMonday = entity.IsEveryMonday,
                            IsEveryTuesday = entity.IsEveryTuesday,
                            IsEveryWednesday = entity.IsEveryWednesday,
                            IsEveryThursday = entity.IsEveryThursday,
                            IsEveryFriday = entity.IsEveryFriday,
                            IsEverySaturday = entity.IsEverySaturday,
                            IsEverySunday = entity.IsEverySunday,
                            IsDayOfMonth = entity.IsDayOfMonth,
                            StartTime = entity.StartTime,
                            EndTime = entity.EndTime,
                            StartDate = entity.StartDate,
                            EndDate = entity.EndDate,
                        });
                    }

                    return new GetDataResponse<IList<ScheduledRepeatItem>> { Success = true, Data = result };
                }
                catch (Exception ex)
                {
                    FileLog.Error("GetScheduleRepeat", ex);
                    return new GetDataResponse<IList<ScheduledRepeatItem>>
                    {
                        Success = false,
                        Error = BusinessLogicError.GetScheduleRepeatFailed
                    };
                }
            }
        }


        public SaveDataResponse<ScheduledRepeatItem> InsertScheduleRepeat(SaveDataRequest<ScheduledRepeatItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var scheduleRepeatEntity = new ScheduleRepeatEntity();
                    scheduleRepeatEntity.ScheduleRepeatId = request.Data.ScheduleRepeatID;
                    scheduleRepeatEntity.IsOneTime = request.Data.IsOneTime;
                    scheduleRepeatEntity.IsEveryMonday = request.Data.IsEveryMonday;
                    scheduleRepeatEntity.IsEveryTuesday = request.Data.IsEveryTuesday;
                    scheduleRepeatEntity.IsEveryWednesday = request.Data.IsEveryWednesday;
                    scheduleRepeatEntity.IsEveryThursday = request.Data.IsEveryThursday;
                    scheduleRepeatEntity.IsEveryFriday = request.Data.IsEveryFriday;
                    scheduleRepeatEntity.IsEverySaturday = request.Data.IsEverySaturday;
                    scheduleRepeatEntity.IsEverySunday = request.Data.IsEverySunday;
                    scheduleRepeatEntity.IsDayOfMonth = request.Data.IsDayOfMonth;
                    scheduleRepeatEntity.StartTime = request.Data.StartTime;
                    scheduleRepeatEntity.EndTime = request.Data.EndTime;
                    scheduleRepeatEntity.StartDate = request.Data.StartDate;
                    scheduleRepeatEntity.EndDate = request.Data.EndDate;

                    if (!adapter.SaveEntity(scheduleRepeatEntity, true))
                        return new SaveDataResponse<ScheduledRepeatItem> { Success = false, Error = BusinessLogicError.InsertScheduleRepeatFailed };

                    // Get ScheduledRepeat entity after insert
                    var q = _queryFactory.Create()
                        .Select(() => new
                        {
                            ScheduleRepeatId = ScheduleRepeatFields.ScheduleRepeatId.Source("sr").ToValue<int>(),
                            IsOneTime = ScheduleRepeatFields.IsOneTime.Source("sr").ToValue<bool>(),
                            IsEveryMonday = ScheduleRepeatFields.IsEveryMonday.Source("sr").ToValue<bool>(),
                            IsEveryTuesday = ScheduleRepeatFields.IsEveryTuesday.Source("sr").ToValue<bool>(),
                            IsEveryWednesday = ScheduleRepeatFields.IsEveryWednesday.Source("sr").ToValue<bool>(),
                            IsEveryThursday = ScheduleRepeatFields.IsEveryThursday.Source("sr").ToValue<bool>(),
                            IsEveryFriday = ScheduleRepeatFields.IsEveryFriday.Source("sr").ToValue<bool>(),
                            IsEverySaturday = ScheduleRepeatFields.IsEverySaturday.Source("sr").ToValue<bool>(),
                            IsEverySunday = ScheduleRepeatFields.IsEverySunday.Source("sr").ToValue<bool>(),
                            IsDayOfMonth = ScheduleRepeatFields.IsDayOfMonth.Source("sr").ToValue<bool>(),
                            StartTime = ScheduleRepeatFields.StartTime.Source("sr").ToValue<TimeSpan>(),
                            EndTime = ScheduleRepeatFields.EndTime.Source("sr").ToValue<TimeSpan>(),
                            StartDate = ScheduleRepeatFields.StartDate.Source("sr").ToValue<DateTime>(),
                            EndDate = ScheduleRepeatFields.EndDate.Source("sr").ToValue<DateTime>(),
                        })
                        .From(_queryFactory.ScheduleRepeat.As("sr"))
                        .Where(ScheduleRepeatFields.ScheduleRepeatId.Source("sr") == scheduleRepeatEntity.ScheduleRepeatId);

                    var val = adapter.FetchQuery(q).FirstOrDefault();
                    if (val == null)
                        return new SaveDataResponse<ScheduledRepeatItem> { Success = false, Error = BusinessLogicError.InsertScheduleRepeatFailed };

                    return new SaveDataResponse<ScheduledRepeatItem>
                    {
                        Success = true,
                        Data = new ScheduledRepeatItem
                        {
                            ScheduleRepeatID = val.ScheduleRepeatId,
                            IsOneTime = val.IsOneTime,
                            IsEveryMonday = val.IsEveryMonday,
                            IsEveryTuesday = val.IsEveryTuesday,
                            IsEveryWednesday = val.IsEveryWednesday,
                            IsEveryThursday = val.IsEveryThursday,
                            IsEveryFriday = val.IsEveryFriday,
                            IsEverySaturday = val.IsEverySaturday,
                            IsEverySunday = val.IsEverySunday,
                            IsDayOfMonth = val.IsDayOfMonth,
                            StartTime = val.StartTime,
                            EndTime = val.EndTime,
                            StartDate = val.StartDate,
                            EndDate = val.EndDate,
                        }
                    };

                    //return null;

                }
                catch (Exception ex)
                {
                    FileLog.Error("InsertScheduleRepeat", ex);
                    return new SaveDataResponse<ScheduledRepeatItem> { Success = false, Error = BusinessLogicError.InsertScheduleRepeatFailed };
                }
            }
        }


        public SaveDataResponse<ScheduledRepeatItem> UpdateScheduleRepeat(SaveDataRequest<ScheduledRepeatItem> request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var scheduledRepeatQuery = _queryFactory.ScheduleRepeat.Where(ScheduleRepeatFields.ScheduleRepeatId == request.Data.ScheduleRepeatID);
                    var scheduledRepeatEntity = adapter.FetchFirst(scheduledRepeatQuery);
                    if (scheduledRepeatEntity == null)
                        return new SaveDataResponse<ScheduledRepeatItem> { Success = false, Error = BusinessLogicError.ScheduleRepeatDoesNotExist };

                    scheduledRepeatEntity.ScheduleRepeatId = request.Data.ScheduleRepeatID;
                    scheduledRepeatEntity.IsOneTime = request.Data.IsOneTime;
                    scheduledRepeatEntity.IsEveryMonday = request.Data.IsEveryMonday;
                    scheduledRepeatEntity.IsEveryTuesday = request.Data.IsEveryTuesday;
                    scheduledRepeatEntity.IsEveryWednesday = request.Data.IsEveryWednesday;
                    scheduledRepeatEntity.IsEveryThursday = request.Data.IsEveryThursday;
                    scheduledRepeatEntity.IsEveryFriday = request.Data.IsEveryFriday;
                    scheduledRepeatEntity.IsEverySaturday = request.Data.IsEverySaturday;
                    scheduledRepeatEntity.IsEverySunday = request.Data.IsEverySunday;
                    scheduledRepeatEntity.IsDayOfMonth = request.Data.IsDayOfMonth;
                    scheduledRepeatEntity.StartTime = request.Data.StartTime;
                    scheduledRepeatEntity.EndTime = request.Data.EndTime;
                    scheduledRepeatEntity.StartDate = request.Data.StartDate;
                    scheduledRepeatEntity.EndDate = request.Data.EndDate;

                    if (!adapter.SaveEntity(scheduledRepeatEntity))
                        return new SaveDataResponse<ScheduledRepeatItem> { Success = false, Error = BusinessLogicError.UpdateScheduleRepeatFailed };


                    // Get rollupDef entity after updated
                    var q = _queryFactory.Create()
                        .Select(() => new
                        {
                            ScheduleRepeatId = ScheduleRepeatFields.ScheduleRepeatId.Source("sr").ToValue<int>(),
                            IsOneTime = ScheduleRepeatFields.IsOneTime.Source("sr").ToValue<bool>(),
                            IsEveryMonday = ScheduleRepeatFields.IsEveryMonday.Source("sr").ToValue<bool>(),
                            IsEveryTuesday = ScheduleRepeatFields.IsEveryTuesday.Source("sr").ToValue<bool>(),
                            IsEveryWednesday = ScheduleRepeatFields.IsEveryWednesday.Source("sr").ToValue<bool>(),
                            IsEveryThursday = ScheduleRepeatFields.IsEveryThursday.Source("sr").ToValue<bool>(),
                            IsEveryFriday = ScheduleRepeatFields.IsEveryFriday.Source("sr").ToValue<bool>(),
                            IsEverySaturday = ScheduleRepeatFields.IsEverySaturday.Source("sr").ToValue<bool>(),
                            IsEverySunday = ScheduleRepeatFields.IsEverySunday.Source("sr").ToValue<bool>(),
                            IsDayOfMonth = ScheduleRepeatFields.IsDayOfMonth.Source("sr").ToValue<bool>(),
                            StartTime = ScheduleRepeatFields.StartTime.Source("sr").ToValue<TimeSpan>(),
                            EndTime = ScheduleRepeatFields.EndTime.Source("sr").ToValue<TimeSpan>(),
                            StartDate = ScheduleRepeatFields.StartDate.Source("sr").ToValue<DateTime>(),
                            EndDate = ScheduleRepeatFields.EndDate.Source("sr").ToValue<DateTime>(),
                        })
                        .From(_queryFactory.ScheduleRepeat.As("sr"))
                        .Where(ScheduleRepeatFields.ScheduleRepeatId.Source("sr") == request.Data.ScheduleRepeatID);

                    var val = adapter.FetchQuery(q).FirstOrDefault();
                    if (val == null)
                        return new SaveDataResponse<ScheduledRepeatItem> { Success = false, Error = BusinessLogicError.UpdateScheduleRepeatFailed };

                    return new SaveDataResponse<ScheduledRepeatItem>
                    {
                        Success = true,
                        Data = new ScheduledRepeatItem
                        {
                            ScheduleRepeatID = val.ScheduleRepeatId,
                            IsOneTime = val.IsOneTime,
                            IsEveryMonday = val.IsEveryMonday,
                            IsEveryTuesday = val.IsEveryTuesday,
                            IsEveryWednesday = val.IsEveryWednesday,
                            IsEveryThursday = val.IsEveryThursday,
                            IsEveryFriday = val.IsEveryFriday,
                            IsEverySaturday = val.IsEverySaturday,
                            IsEverySunday = val.IsEverySunday,
                            IsDayOfMonth = val.IsDayOfMonth,
                            StartTime = val.StartTime,
                            EndTime = val.EndTime,
                            StartDate = val.StartDate,
                            EndDate = val.EndDate,
                        }
                    };
                }
                catch (Exception ex)
                {
                    FileLog.Error("UpdateScheduledRepeat", ex);
                    return new SaveDataResponse<ScheduledRepeatItem> { Success = false, Error = BusinessLogicError.UpdateScheduleRepeatFailed };
                }
            }
        }


        public DeleteDataResponse DeleteScheduledRepeat(DeleteDataRequest request)
        {
            using (var adapter = new DataAccessAdapter())
            {
                try
                {
                    var query = _queryFactory.ScheduleRepeat.Where(ScheduleRepeatFields.ScheduleRepeatId == request.DataId);
                    var scheduledRepeatEntity = adapter.FetchFirst(query);
                    if (scheduledRepeatEntity == null)
                        return new DeleteDataResponse { Error = BusinessLogicError.ScheduleRepeatDoesNotExist, Success = false };

                    if (!adapter.DeleteEntity(scheduledRepeatEntity))
                        return new DeleteDataResponse { Error = BusinessLogicError.DeleteScheduleRepeatFailed, Success = false };

                    return new DeleteDataResponse { Success = true, DataId = request.DataId };
                }
                catch
                {
                    return new DeleteDataResponse { Success = false, Error = BusinessLogicError.DeleteScheduleRepeatFailed };
                }
            }
        }



        #endregion
    }
}
